When we run Jobs, it creates a container (runner) that supports Ubuntu, Windows, and MacOS. In the container we can install software, use the installed software to help us process some data, and then push the processed data somewhere.
In this article, we’ll introduce the use of GitHub Actions to automate the deployment of Hexo to GitHub Pages. Generally, blogs that use Hexo use hexo generate --deploy
to deploy, but this can take a long time if there are a lot of articles, or if the local node.js version is not compatible with Hexo. Using GitHub Actions helps you to avoid these situations.
blog
and xxx.github.io
repositoryYou need two Git repositories, one for the blog source repository blog
and one for the static page repository xxx.github.io
The blog source repository, blog
, can be private.
The static page repository xxx.github.io
, which must be public.
Create a key using ssh-keygen (you can also use id_rsa if you want)
In the blog source code repository page, add new secret
via setting -> Security -> Secrets -> Actions -> New repository secret
. The content is the private key.
In the static page repository page, add new Deploy keys
via setting -> Security -> Deploy keys
. The content is the public key. And select “Allow Write Access”.
Create a .github/workflows/xxx.yml file in the root of the blog source repository
1 | name: HEXO_DEPLOY |
Meaning of the parameters
here on.push.branches.$.master
means that the task will be executed when the master branch receives the push. ubuntu-latest
, windows-latest
, macos-latest
.Finally, just push the file to the master branch
]]>A C++ PWN problem, the source code can be seen after decompiling by ida pro
A stack overflow vulnerability can be quickly discovered by decompiling the code
Debugging with gdb, pattern_create 100 after the input generated error messages
It can be calculated that the offset is 40 bytes, after inputting 40 bytes of data can overwrite the subsequent 8 bytes of return address
Use the following shellcode (execve([“/bin/sh”],[],[]))
1 | 0: 31 f6 xor esi, esi |
Get flag
Here is the attack script:
1 | from pwn import * |
_JUNK_FUN_0((3 * dword_100910C0 * dword_100910C4 * dword_100910CC + 4096) | (dword_100910C4+ dword_100910D0+ 2 * (4096 - dword_100910C8)- dword_100910C0 * dword_100910CC+ 3 * dword_100910D4),(2 * (dword_100910D0 * (dword_100910D4 + dword_100910D0) + dword_100910C8 * (dword_100910C4 * dword_100910C8 * dword_100910C8 + 2) + 4 * (dword_100910C0 - dword_100910CC) + 4096 - dword_100910D4)) | (6 * (2 * dword_100910C4- dword_100910D4 * (dword_100910C8 * dword_100910CC + 1) - dword_100910CC) + dword_100910D0* (6* (dword_100910C0 * dword_100910C8 * dword_100910D0 - dword_100910C4 * dword_100910D4)- 6)+ 4096))
]]>Character device driver, block device driver and network device driver as the linux kernel three major driver devices, character devices mainly complete the byte read and write operations, common applications are mouse, keyboard, etc., the structure form is shown below:
1 | struct cdev { |
1 | void cdev_init(struct cdev *, struct file_operations *); // Used to initialize the members of cdev and establish the connection between cdev and file_operation |
1 | int register_chrdev_region(dev_t from, unsigned count, const char *name); // Known starting device number |
Create a new dev folder and create mydev.c and the corresponding Makefile file in this directory
The mydev.c program is as follows:
1 |
|
The Makefile program is as follows:
1 | mydev.o |
dmesg -c
cat /proc/devices
Create the mydevTest.c test file with the following code:
1 |
|
Type gcc mydevTest.c a.out to generate a.out, then type . /a.out to run.
mydev: loading out-of-tree module taints kernel.
mydev: module verification failed: signature and/or required key missing - tainting kernel
are the very beginning of the Linux source code .config, which will be shown in this experiment but does not affect
If there is no CONFIG_MODULE_SIG=n statement in the Makefile file, then the hello.txt file will show
module verification failed: signature and/or required key missing - tainting kernel
i.e.: Module verification failed.
1 | //select_and_show.c |
1 | //show_all.c |
1 | obj-m := show_all.o |
MODULE_LICENSE("GPL");
1 | MODULE_LICENSE(_license) // _license is the license name string |
From kernel version 2.4.10 on, modules must declare the license of this module via the MODULE_LICENSE macro, otherwise you will receive a warning that the kernel is contaminated with “kernel tainted” when loading this module. As we can see from the linux/module.h file, the meaningful licenses accepted by the kernel are “GPL”, “GPL v2”, “GPL and additional rights”, “Dual BSD/GPL”, “Dual MPL/GPL”, “Proprietary “.
Find the include\linux\init.h
file in the kernel source code directory
1 |
If this is a macro definition, then what is __initcall(x)
?
1 |
|
initcalls
1 |
We can see very many xxx_initcall
macro function definitions, they are all implemented by __define_initcall
. Inside __define_initcall
there are two parameters, one is fn and the other is id.
The function do_initcalls
can be found in the init\main.c
file
1 | static void __init do_initcalls(void) |
do_initcalls
seems to be mainly a for loop, which is executing some functions by level
.
So the question arises, what is level
and what function is executed, but this goes back to the above macro definition, first a simple wave of macro definition process
module_init(fn)---> __initcall(fn) ---> device_initcall(fn) ---> __define_initcall(fn, 6)
1 |
|
In the macro definition above, ##
can mean a connection, and __initcall_##fn##id
is __initcall_fnid
When fn
is helloworld
and id
is 4
, __initcall_##fn##id
is __initcall_helloworld4
A single #
symbol can be stringified, and #id
for "id"
TODO…
1 | // Emergency event message, prompted before a system crash, indicating that the system is unavailable |
1 | volatile long state; /* -1为不可运行,0可以运行,大于0表示停止 */ |
The process in Linux consists of multiple states, and during operation, the process will switch in multiple situations with scheduling, and the information of the process is the basis for the process to make scheduling swaps
State | Meaning |
---|---|
TASK_RUNNING | Runnable |
TASK_INTERRUPTIBLE | Waiting |
TASK_UNINTERRUPTIBLE | Uninterruptible waiting |
TASK_ZOMBIE | Zombie |
TASK_STOPPED | Pause |
TASK_SWAPPING | Switching in/out |
1 | unsigned int flags; /* per process flags, defined below */ |
Used by the kernel to identify the state of the current process for the next operation
Flag | Meaning |
---|---|
PF_FORKNOEXEC | The process has just been created and has not yet been executed |
PF_SUPERPRIV | Super User Privileges |
PF_DUMPCORE | Catching of exceptions |
PF_SIGNALED | Process killed by signal |
PF_EXIRING | The process begins to close |
1 | pid_t pid; //Identifier of the process |
1 | struct task_struct *real_parent; /* real parent process */ |
Processes are created with an inheritance relationship; a process can create multiple child processes, which are the parents of these child processes, and these child processes have a sibling relationship with each other.
When creating a child process, the child process inherits most of the information from the parent process, which means that the child process copies most of the information from the task_struct structure of the parent process, except for the pid, and thus the system needs to record these relatives in order to collaborate between processes.
The task_struct structure of each process contains a number of pointers that connect the task _struct structures of all the processes to form a process tree.
Relatives | Meaning |
---|---|
real_parent | real parent |
parent | parent process |
children | The head of the chain table, all elements of the chain table are its child processes |
sibling | Insert the current process into the sibling chain |
group_leader | Points to the first entry in its process group| |
1 | unsigned int ptrace; |
The ptrace system call provides the ability for the parent process to observe and control the execution of the child process, and allows the parent process to check and replace the values of the child process’ kernel image (including registers).
Basic principle: When ptrace tracing is used, all signals sent to the traced child process are forwarded to the parent process, which is blocked. And after the parent process receives the signal, it can check and modify the stopped child process, and then let the child process continue to run. Please our common debugging tool gdb is based on ptrace to implement it.
1 | const struct sched_class *sched_class; |
sched_class: Scheduling Class
se: Calling entities for common processes, each process has one of these entities
rt: Real-time process call entities, each process has one of these entities
Process scheduling uses this information to determine a limited order of process execution, combined with process state information to ensure that processes run in a reasonable and orderly manner. Processes have various scheduling information, as follows.
Name | Meaning | Usage |
---|---|---|
SCHED_OTHER | Other scheduling methods | Normal process |
SCHED_FIFO | First in first out | Real-time processes |
SCHED_RR | Round-Robin | Real-time processes |
1 | int prio, static_prio, normal_prio; |
Name | Priority |
---|---|
prio | Dynamic Priority |
static_prio | Static Priority |
normal_prio | Normal Priority |
rt_prio | Real-time Priority |
static_prio = MAX_RT_PRIO + nice +20
. The value of MAX_RT_PRIO is 100, and the range of nice range is -20 to +19, so the static_prio value ranges from 100 to 139. The smaller the value of static_prio, the higher the static priority of the process.prio = MAX_RT_PRIO-1 - p->rt_priority;
it can be seen that the larger the value of rt_priority, the smaller the value of prio, so the larger the value of real time priority (rt_priority) means the higher the priority of the process.1 | cputime_t utime, stime, utimescaled, stimescaled; |
Name | Meaning |
---|---|
utime/stime | Record the timers passed by the process in user/kernel state |
utimescaled/stimescaled | Record the runtime of the process in user/kernel state |
gtime | Virtual machine time counted in beats |
prev_utime/prev_stime | Previous running time |
nvcsw/nivcsw | Voluntary/Involuntary Context Switching Count |
start_time/real_start_time | Process creation time / the latter includes sleep time| |
cputime_expires | Count the processor time of a process or process group being tracked| |
|min_flt, maj_flt | Missing page statistics| |
1 |
|
If multiple processes are performing collaboration on a task, then it is necessary that these incoming processes can access each other’s resources and communicate with each other.
The main process communication methods in Linux are:
1 | /* file system info */ |
define | Meaning |
---|---|
struct fs_struct *fs | Processes can be executed on the system where they affect |
struct files_struct *files | Files opened by the process |
Processes can open or close files, which are system resources, and the Linux kernel has to keep a record of how the process uses the files.
There are two data structures in the task_struct structure to describe the information related to the process pre-file.
The fs _struct describes two VFS index nodes, called root and pwd, which point to the root and current or working directories corresponding to the process’s executable impact, respectively.
The file _struct structure is used to record the descriptors of the files opened by the process.
1 | struct signal_struct *signal; |
name | Meaning |
---|---|
signal | Signal descriptor pointing to the process |
sighand | Signal handler descriptor pointing to the process |
blocked | Indicates the mask of the blocked signal, real_blocked indicates a temporary mask |
pending | Data structure for storing private pending signals |
saa_ss_sp | Alternate stack address for signal handlers, ass_ss_size indicates the stack size |
notifier_data/notifier_mask | The device driver uses the function pointed to by the notifier to block certain semaphores of the process. notifier_data is the data that may be used by the function pointed to by the notifier |
1 | struct mm_struct *mm, *active_mm; |
define | Meaning |
---|---|
struct mm_struct *mm | Describe the address space of the process |
struct mm_struct *activa_mm | Address space borrowed by kernel threads |
mm_struct is used to describe the address space (virtual space) of each process. active_mm is introduced for kernel threads, because kernel threads do not have their own address space. In order to make kernel threads have a uniform context switch with ordinary processes, when a kernel thread makes a context switch, let the active_mm of the switched-in thread point to the active_mm of the process that has just been dispatched out.
When there is not enough physical memory, the Linux memory management system needs to transfer some pages from memory to external memory, and the swap is done on a page-by-page basis.
define | Meaning |
---|---|
int swappable | Whether the memory pages occupied by the process can be swapped out |
unsigned long min_flat, maj_flt, nswap | The accumulated number of missing pages, the master count and the accumulated number of pages swapped out and in of the process |
unsigned long cmin_flat, cnswap | Cumulative number of sub-page misses, pages swapped in, for this process as an ancestor process, for all its hierarchical child processes| |
struct task_struct *next_task, *prev_task;
// All processes (in the form of PCBs) form a two-way chain. next_task and prev_task are the front and back pointers to the chain. The head and tail of the chain are init_task (i.e. process 0).
struct task_struct *next_run, *prev_run;
// The run_queue is a two-way circular chain of processes that are running or can be run with the process status TASK_RUNNING. The front and back pointers of the chain are next_run and prev_run, and the head and tail of the chain are both init_task (i.e. process 0).
struct task_struct *p_opptr, *p_pptr;
和struct task_struct *p_cptr, *p_ysptr, *p_osptr;
// The above are pointers to the original parent, parent, youngest child, and newer and older sibling processes respectively.
TODO…
init_task is the first process of the kernel, process number 0, which becomes idle process when the initialization of the kernel is completed
init_task is a task_struct prototype for all processes and threads in the kernel. During kernel initialization, a task_struct interface is constructed by static definition, named init_task, and then a new kernel init thread, kthreadd kernel thread, is created by the rest_init() function later in the kernel initialization
The kernel init thread, which eventually executes the /sbin/init process, becomes the root process of all user state programs (as shown by the pstree command), i.e. the user space init process
The first init is a kernel thread created by kthread_thread, which, after initialization, moves to user space and generates the ancestors of all user processes
kernel kthreadd kernel thread, becomes the parent of all other daemon threads in the kernel state.
Its task is to manage and schedule other kernel threads kernel_thread, which loops through a kthread function that runs the kthreads maintained in the kthread_create_list global chain, and the kernel threads created when we call kernel_thread are added to this chain, so all kernel threads are directly or indirectly parented to kthreadd
The kernel will use the init_task as its task_struct structure descriptor, and when the system has nothing else to do, it will schedule its execution. At this point, the kernel will become an idle process, giving up the CPU and putting itself to sleep in a continuous loop.
The process init_task
is defined in init/init_task.c
1 | /* Initial task structure */ |
The macro for INIT_TASK
is defined in include/linux/init_task.h
1 |
|
We can see that the stack of the init_task
process is pointing to the init_thread_info
In the file arch/arm/include/asm/thread_info.h
, init_thread_info
is defined as follows
1 |
init_thread_info
is a member of thread_info
of init_thread_union
Variable init_thread_info
is defined in init/init_task.c
.
1 | union thread_union init_thread_union __init_task_data = |
init_thread_union
variable of type thread_union
, then assigns values to the thread_info
member of init_thread_union
, mainly init_thread_union.thread_info thread_info. task=&init_task
, pointing the task
member of this variable to init_task
.attribute((section(".data...init_task"))
, specifying that the section
name is .data...init_task
, will be compiled into vmlinux
at the beginning of .data
.1 | 243 .data : AT(__data_loc) { |
TODO
1 |
Start with init_task and iterate through all processes
Linux interlinks the task structures of all processes into a circular bidirectional chain, like (&init_task)->next ! = &init_task goes on and on
1 | struct task_struct *pid_task(struct pid *pid, enum pid_type type) |
For the explanation of the three parameters of module_param.
module_param(worldNum,int,0644);
The first parameter is the name of the parameter, defined by yourself
The second parameter is the type of the variable, such as int, long, char, float, etc.
The third parameter is the permission, similar to the permission of a file. Here it should mean which users can modify the meaning of this parameter.
1 | * @perm is 0 if the the variable is not to appear in sysfs, or 0444 |
Translated with www.DeepL.com/Translator (free version)
1 | /** |
1 |
|
卡拉兹(Callatz)猜想:
对任何一个正整数 $n$,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 $(3n+1)$ 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 $n=1$。卡拉兹在 1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 $(3n+1)$,以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……
我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 $n$,简单地数一下,需要多少步(砍几下)才能得到 $n=1$?
输入格式:
每个测试输入包含 1 个测试用例,即给出正整数 $n$ 的值。
输出格式:
输出从 $n$ 计算到 1 需要的步数。
输入样例:
3
输出样例:
5
1 |
|
读入一个正整数 $n$,计算其各位数字之和,用汉语拼音写出和的每一位数字。
输入格式:
每个测试输入包含 1 个测试用例,即给出自然数 $n$ 的值。这里保证 $n$ 小于 10100
输出格式:
在一行内输出 $n$ 的各位数字之和的每一位,拼音数字间有 1 空格,但一行中最后一个拼音数字后没有空格。
输入样例:
1234567890987654321123456789
输出样例:
yi san wu
1 |
|
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
- 字符串中必须仅有
P
、A
、T
这三种字符,不可以包含其它字符;- 任意形如
xPATx
的字符串都可以获得“答案正确”,其中x
或者是空字符串,或者是仅由字母A
组成的字符串;- 如果
aPbTc
是正确的,那么aPbATca
也是正确的,其中a
、b
、c
均或者是空字符串,或者是仅由字母A
组成的字符串。现在就请你为PAT写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
输入格式:
每个测试输入包含 1 个测试用例。第 1 行给出一个正整数 $n(<10)$,是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过 100,且不包含空格。
输出格式:
每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出 YES,否则输出 NO。
输入样例:
1 | 8 |
输出样例:
1 | YES |
1 |
|
读入 $n$ $(n>0)$名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。
输入格式:
每个测试输入包含 1 个测试用例,格式为
1
2
3
4
5 >第 1 行:正整数 n
>第 2 行:第 1 个学生的姓名 学号 成绩
>第 3 行:第 2 个学生的姓名 学号 成绩
... ... ...
>第 n+1 行:第 n 个学生的姓名 学号 成绩其中
姓名
和学号
均为不超过 10 个字符的字符串,成绩为 0 到 100 之间的一个整数,这里保证在一组测试用例中没有两个学生的成绩是相同的。
输出格式:
对每个测试用例输出 2 行,第 1 行是成绩最高学生的姓名和学号,第 2 行是成绩最低学生的姓名和学号,字符串间有 1 空格。
输入样例:
1 | 3 |
输出样例:
1 | Mike CS991301 |
1 |
|
卡拉兹(Callatz)猜想已经在1001中给出了描述。在这个题目里,情况稍微有些复杂。
当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数。例如对 n=3 进行验证的时候,我们需要计算 3、5、8、4、2、1,则当我们对 n = 5、8、4、2 进行验证的时候,就可以直接判定卡拉兹猜想的真伪,而不需要重复计算,因为这 4 个数已经在验证3的时候遇到过了,我们称 5、8、4、2 是被 3“覆盖”的数。我们称一个数列中的某个数 n 为“关键数”,如果 n 不能被数列中的其他数字所覆盖。
现在给定一系列待验证的数字,我们只需要验证其中的几个关键数,就可以不必再重复验证余下的数字。你的任务就是找出这些关键数字,并按从大到小的顺序输出它们。
输入格式:
每个测试输入包含 1 个测试用例,第 1 行给出一个正整数 $K(<100)$,第 2 行给出 $K$ 个互不相同的待验证的正整数 $n$ $(1<n≤100)$的值,数字间用空格隔开。
输出格式:
每个测试用例的输出占一行,按从大到小的顺序输出关键数字。数字间用 1 个空格隔开,但一行中最后一个数字后没有空格。
输入样例:
1 | 6 |
输出样例:
7 6
1 |
|
让我们用字母
B
来表示“百”、字母S
表示“十”,用12...n
来表示不为零的个位数字n
$(<10)$,换个格式来输出任一个不超过 3 位的正整数。例如234
应该被输出为BBSSS1234
,因为它有 2 个“百”、3 个“十”、以及个位的 4。
输入格式:
每个测试输入包含 1 个测试用例,给出正整数 $n(<1000)$。
输出格式:
每个测试用例的输出占一行,用规定的格式输出 n。
输入样例 1:
234
输出样例 1:
BBSSS1234
输入样例 2:
23
输出样例 2:
SS123
1 |
|
让我们定义dn为:dn = pn+1 - pn,其中pi是第i个素数。显然有d1 = 1,且对于$n>1$有dn是偶数。“素数对猜想”认为“存在无穷多对相邻且差为 2 的素数”。
现给定任意正整数
N
(<105),请计算不超过N
的满足猜想的素数对的个数。
输入格式:
输入在一行给出正整数
N
。
输出格式:
在一行中输出不超过
N
的满足猜想的素数对的个数。
输入样例:
20
输出样例:
4
1 |
|
This is a successful method and seems to be the one most people use
First, go to include/linux/syscalls.h
and add the following function prototype
After that, go to arch/x86/entry/syscalls/syscall_32.tbl
and arch/x86/entry/syscalls/syscall_64.tbl
respectively and add the system call number
ps:Make sure to add __ia32_
to syscall_32.tbl
and __x64_
to syscall_64.tbl
, just like the picture above, otherwise you may get an error like underfined reference to xxx
.
Add code in kernel/sys.c
After that just make -j8 bzImage
and wait for a few minutes
After compiling, write a demo to see if it works
Then use the script to make the rootfs.img and launch qemu
Let’s talk about this syscall
1 | SYSCALL_DEFINE5(lab1, pid_t, pid, int, flag, int, nicevalue, void __user *, prio, void __user *, nice) { |
There seems to be a lot of questions though…. Didn’t think about the range of nice values when I first wrote it (didn’t even know nice values had a range).
At first, I wanted to follow a tutorial on the Internet and try to write a method with parameters, similar to the one I wrote in the last blog about adding system calls.
Create lab1_v2
folder in the root of the source code and add lab1_v2.c
and Makefile
Modify the Makefile
file in the root directory of the source code
Complete the regular three-step include/linux/syscalls.h
, arch/x86/entry/syscalls/syscall_32.tbl
and arch/x86/entry/syscalls/syscall_64.tbl
Then compile the kernel make -j8 bzImage
Written a demo as usual
Then an error occurs when running
Probably something went wrong when passing parameters?
find_get_pid(int nr)
1 | struct pid |
pid_task()
1 | //Find pid_task by process descriptor |
asmlinkage
Inform the compiler to extract the function parameters from the stack only, not from the registers, because the system has already pressed the parameter values passed through the registers into the kernel stack before executing the service routine
set_user_nice()
1 | void set_user_nice(struct task_struct *p, long nice) |
Download kernel source code: https://www.kernel.org/
Install necessary dependencies
1 | sudo apt-get update |
Unzip and enter the directory
1 | make menuconfig |
ps: There may be errors that require flex and bison, apt-get install can fix them
Nothing should be changed, just save
1 | enter kernel hacking |
ps: Remember not to make the terminal window too small when make menuconfig
. Otherwise you will be prompted and not allowed to complete the next steps.
```bash
make bzImage
Setup is 17244 bytes (padded to 17408 bytes).
System is 7666 kB
CRC 5c77cbfe
Kernel: arch/x86/boot/bzImage is ready (#1)
1 |
|
Then go to the Makefile
in the root of the source code and add helloworld/
Then go to include/linux/syscalls.h
and add the function prototype
Add system call numbers to arch/x86/entry/syscalls/syscall_32.tbl
and arch/x86/entry/syscalls/syscall_64.tbl
After that, compile the kernel
1 | make bzImage |
It will be able to get bzImage
in ./arch/x86/boot/
As usual, download from the official website https://busybox.net/
Unzip and enter the directory
1 | make menuconfig |
Selected Build static binary (no shared libs)
within Settings
1 | make install |
After compiling, a _install
directory will appear, then:
1 | $ cd _install |
Here using source code compilation
1 | wget https://download.qemu.org/qemu-4.1.0.tar.xz |
Get a script from veritas501
1 | $ ls |
Run Script
1 | $ ./runqemu |
Done!
As well, thanks for MiGo and Aris’ guidance OWO
Freely write
pkg-config not found
sudo apt-get install pkg-config
glib-2.40 gthread-2.0 is required to compile QEMU
Use apt-cache search all | grep glib
to find glib, can find glib’s name is libglib2.0-dev
, then apt install libglib2.0-dev
ERROR: pixman >= 0.21.8 not present.
Please install the pixman devel package.
Solution:
Use apt-cache search pixman
to find, then apt install libpixman-1-dev
Virtual machines remember to enable CPU virtualization
VNC server running on 127.0.0.1:5900
sudo apt-get install libsdl1.2-dev
sudo apt-get install gcc libsdl1.2-dev zlib1g-dev libasound2-dev pkg-config libgnutls-dev pciutils-dev
sudo apt-get install libsdl2-dev
sudo apt-get install libsdl2-2.0
sudo apt install libelf-dev
]]>1 | import re, math |
This is the top of the whole project, and then it is separate to each module
This Phase-Locked Loop is used for dividing the frequency. My FPGA board is a Cyclone IV and comes with a 20MHz clock signal. The buzzer needs 1MHz, the music needs 4KHz, and the VGA display 640 * 480 * 60Hz needs 25MHz
This is the music module, mainly divided into the number of notes recorded constep, recorded notes Rom, notes converted into buzzer frequency INX2CODE and sound SPK0
The constep is simply a counter that records the number of notes stored in the mif.
The ROM is needed to turn the score into a mif file and then use the ROM module to generate the device.
1 | module INX2CODE (INX, F_CODE); |
Convert the image to bmp format, then to mif, and save it to ROM like a note to generate a device.
1 | module vga_driver( |
1 | module choose2_1( |
I do not have a VGA monitor can only go to a friend’s bedroom to play ~
Source code: Github
]]>The original plan was not to give the source code to come. Then I was told that if I didn’t give the source code, it would be impossible for people to solve it. And there was no easy Challenge, so the source code was given.
Okay, the process of solving this Challenge:
First of all, open the website and then look at F12, the comments hinted that there was source.php, a simple php audit, you can find that the problem appears in the following code
1 | $_page = urldecode($page); |
It can be bypassed with %253f, combined with the flag in ffffllllaaaagggg in hint.php (Sorry. Seems like I should have told flag in / in the challenge description)…
]]>1 | # Level 1 Heading |
1 | ## Level 2 heading |
1 | ### Level 3 heading |
1 | #### Level 4 heading |
1 | ##### Level 5 heading |
1 | ###### Level 6 heading |
Error Cases
####### 7 Up to level 6 only
1 | ####### 7 |
1 | ######## 8 |
If it is on the top line of === or ---, it will automatically become a title (corresponding to Level 1 and Level 2)
This is a quote!
And
it can
overlay
seems that you can always add…
1 | > This is a quote! |
Meow Meow
Meow Meow
Meow Meow
1 | > Meow Meow |
It needs a line break to get the quote out
Bold
Italic
Also italic
Bold and italic
delete
1 | **Bold** |
1 | --- |
Why can’t you add text in the middle of the split line?  ̄へ ̄
Non-numeric list
1 | + dot (〃'▽'〃) |
Numbers List
1 | 1. o( ̄▽ ̄)d |
List indent
1 | 1. First |
What to write? | I don’t know… | Then write freely. |
---|---|---|
This is the content | This is also content | also~ |
Without a colon or colon on the left | Both left and right is centered | On the right is the right |
1 | |What to write?|I don't know...|Then write freely.| |
1 |
|
1 | ``` c++ |
If it’s a single line of code, you can just `code`
print "Welcome to my blog~"
1 | `print "Welcome to my blog~"` |
``` can be combined with setting code highlighting
1 | ![avatar~](https://i.loli.net/2018/10/10/5bbdef9771e6a.jpg "avatar") |
1 | + [test](https://sm.ms "test") |
混合~
1 | [![Try mixing](https://i.loli.net/2018/10/10/5bbdefcf4bc8f.jpg "Try mixing")](https://aslin.site) |
1 | <lkjlkj174@gmail.com> |
Ctrl
Za
Za
1 | <kbd>Ctrl</kbd> |
1 | - [x] Heading |
Try to translate the original blog, still lack of English skills emmmm
]]>