特殊的gcc语法
对main函数hook__attribute__ 是GCC的特殊语法,利用这个标识符可以支持在main函数之前和main函数执行完毕之后运行一些操作
__attribute__((constructor)) syntax在一个函数前面加上这个标识符,可以使这个函数在 main() 函数之前运行若有多个,按照定义先后顺序运行, 也可constructor(priority)这样显示定义优先级
注意 优先级0~100是作为保留使用的,若使用了可能得到一个Warning constructor priorities from 0 to 100 are reserved for the implementation [-Wprio-ctor-dtor]
__attribute__((destructor)) syntax在一个函数前面加上这个标识符,可以使这个函数在 main() 函数之后运行
同样也有优先级,同上.
e.g. 使用示例
1234567891011121314###include <cstdio>__attribute__((constructor)) vo ...
gdb使用技巧
GDB调试工具0x00 介绍gdb是用来debug c/c++程序的工具,用来检测程序的逻辑错误 要想使用必须在gcc编译的时候加上-g选项 加了-g之后会生成调试表
GDB的三种调试方式如下:
运行并调试一个新进程:
运行GDB, 并通过命令行或 file命令指定目标程序;
输入run命令, GDB将进行以下操作:
通过 fork() 系统调用创建一个子进程;
在新创建的子进程中执行操作ptrace(PTRACE_TRACEME, 0, 0, 0);
在子进程中通过execv()系统调用加载用户指定的可执行文件。
attach 并调试一个已经运行的进程:
用户确定需要进行调试的进程PID
运行GDB, 输入 attach <pid>, 或者gdb -p <pid>
GDB会对其执行操作ptrace(PTRACE_ATTACH, 0, 0, 0);
远程调试目标机上新创建的进程:
gdb 运行在调试机上,gdbserver 运行在被调试机上,两者之间的通信数据格式为GDB串行协议(Remote Serial Protoc ...
golang泛型机制
What is Generic Mechanism面向对象的一个重要目标就是对代码复用的支持。支持这个目标的一个重要机制就是泛型机制(generic mechanism): 如果除去对象的基本类型外,实现方法是相同的,那么我们就可以用泛型实现(generic implementation) 来描述这种基本的功能。
GOlang 在1.18之后的版本开始支持泛型了.函数要支持泛型机制,需要有2个前提:
对于函数而言,需要一种方式来声明这个函数到底支持哪些类型的参数
对于调用者而言,需要一种方式去指定给函数传递的参数是什么类型
为了满足以上前提条件:
在声明函数的时候,除了需要像普通函数一样添加函数的形式参数之外, 还要声明这些形参的类型决定因素(type parameters), 从而让函数支持泛型机制,处理不同类型的参数
在函数调用时,除了像普通函数一样传递实参之外,还需要传递泛型函数的类型决定因素的对应类型实参(type arguments)
每个类型决定因素都有类型约束(type contraint), 有点像是类型决定因素的元类型(meta-type), 即约束类型决定因 ...
go编译相关环境变量
影响编译的环境变量
环境变量
说明
GOARCH
指定CPU架构
GOOS
制定编译程序的运行平台
CGO_ENABLED
设置golang编译期间是否支持调用cgo命令
GOARCH and GOOS通常来说, GOARCH和GOOS成对出现
$GOOS
$GOARCH
android
arm
darwin
386, amd64, arm, arm64
dragonfly
amd64
freebsd
386, amd64, arm
linux
386, amd64, arm, arm64, ppc64, ppc64le, mips, mipsle, mips64, mips64le, s390x
netbsd
386, amd64, arm
openbsd
386, amd64, arm
plan9
386, amd64
solaris
amd64
windows
386, amd64
CGO_ENABLED当CGO_ENABLED=1, 进行编译时, 会将文件中引用libc的库(比如常用的net包),以动态链 ...
nmap
nmap0x01 活跃主机发现技术注意:使用任何扫描工具得到的扫描结果仅供参考
nmap主机发现技术分析
nmap中提供了--packet-trace选项来观察nmap发出了哪些数据包,收到了哪些数据包,由此可知nmap在进行主机发现的时候,无论指定了何种方式,nmap都会先判断一下目标主机是否和自己处于同一个子网中,如果处于同一个子网,nmap会直接使用ARP协议扫描的方式,而不会使用你指定的扫描方式
只探测目标主机是否活跃,不进行对于端口扫描
使用参数-sn
之前的版本是-sP参数
命令语法:nmap -sn [ 目标 ]
1.1 基于ARP协议的活跃主机发现技术
原理:
如果想要知道处在同一网段的IP地址为*.*.*.*的主机是否为活跃主机,只需要构建一个ARP请求数据包,并广播出去,如果得到了回应,则说明该主机为活跃主机
优点:
准度高因为不遵守ARP协议将无法通信
缺点:
不能对不同网段的目标主机进行扫描
使用参数-PR
命令语法:nmap -PR [ 目标 ]
1.2 基于ICMP协议的活跃主机发现技术
ICMP协议中包含了很多方法,但 ...
python装饰器详解
0x00 装饰器(decorator)介绍可以查看官方文档对其的介绍:
返回值为另一个函数的函数,通常使用 @wrapper 语法形式来进行函数变换。 装饰器的常见例子包括 classmethod() 和 staticmethod()。
装饰器语法只是一种语法糖,以下两个函数定义在语义上完全等价:
1234567def f(...): ...f = staticmethod(f)@staticmethoddef f(...): ...
同样的概念也适用于类,但通常较少这样使用。有关装饰器的详情可参见 函数定义 和 类定义 的文档。
python装饰器简单来说就是用一切皆对象和代码复用的思想去修改一个可调用对象的功能的函数,以达到让代码更加简洁的效果。这个功能也体现了python简洁 高效的设计哲学。
0x01 一切皆对象python中的函数是一个函数对象.python内存空间的存储特点:python右值对应一个内存空间,而变量名为这片内存的引用(用C++来理解的话,右值为对象,左值为这个对象的引用)。
12345678910111213141516171819 ...
linux信号总结
信号A给B发送信号,B收到信号之前执行自己的代码,收到信号后,不管执行到程序的什么位置,都要暂停执行,去处理信号,处理完毕后在继续执行。与硬件中断类似(异步模式)。但信号是软件层面上实现的中断,早期被称为软中断.
信号的共性:简单、不能携带大量信息、满足条件才能发送。
信号的特质:由于信号是通过软件方法实现,其实现手段导致信号有很强的延时性。但对用户来说,这个延迟时间非常短,不易察觉。
每个进程收到的所有信号,都是由内核负责发送以及处理的
与信号相关的事件和状态产生信号的方式如下表:
事件
例子
按键产生
Ctrl+c、Ctrl+z、Ctrl+\
系统调用产生
kill、raise、 abort
软件条件产生
定时器alarm
硬件异常产生
非法访问内存(段错误)、除0(浮点数例外)、内存对齐出错(总线错误)
命令产生
kill
递达:递送并且到达进程。未决:产生和递达之间的状态。主要由于阻塞(屏蔽)导致该状态
信号处理的方式:
执行默认动作(即进程不去处理)
忽略(丢弃)
捕捉(调用用户处理函数)
在linux的实现PCB的结构体task_s ...
进程间通信相关系统调用
进程间通信在进程间完成数据传递需要借助操作系统提供的特殊方法,如:文件、管道、信号、共享内存、消息队列、套接字、命名管道等。而现今常用的进程间通信方法有:
管道(使用最简单)
信号(开销最小)
共享映射区(无血缘关系)
本地套接字(最稳定)
0x01 匿名管道
注:0x01中的管道都指匿名或者无名管道
管道是一种最基本的IPC机制,作用于有血缘关系的进程之间,完成数据传递。调用pipe系统函数即可创建一个管道,有如下特性:
其本质是一个伪文件(实为内核缓冲区)
由两个文件描述符引用,一个表示读端,一个表示写端。
规定数据从管道的写端流入管道,读端流出。
管道的原理:管道实为内核使用环形队列机制,借助内核缓冲区(4k)实现。
管道的局限性:
数据不能进程自己写,自己读。
管道中的数据不能反复读取。一旦读走,管道中不再存在。
采用半双工通信方式,数据只能在单方向上流动。
pipe函数
pipe函数用来创建并打开无名管道。它首先在系统的文件表中取得两个表项,然后在当前进程的文件描述符表中也同样寻找两个未使用的描述符表项,用来保存相应的文件结构指针。接 ...
进程控制相关函数
进程进程相关概念解释程序与进程的区别
程序: 死的,存在硬盘上,只占用磁盘空间。 — 剧本
进程:活动。运行在内存中的程序。占用内存、cpu等资源。 — 戏
虚拟内存与物理内存的映射关系
PCB:进程控制块
MMU:内存管理单元,在CPU内部
. src=”./DeepinScreenshot_select-area_20200506155851.png” style=”zoom:100%;” />
进入到系统调用实际上就是靠的MMU进行权级切换
PCB 进程控制块
每个进程在内核中都有一个进程控制块(PCB)来维护进程相关信息,linux内核的进程块是task_struct结构体
/usr/linux-headers-xx.xx.x-x/include/linux/sched.h 文件中可以查看 struct task_struct结构体定义
其内部成员有很多,重点掌握以下部分即可:
进程ID:系统中每个进程有唯一的id,在c语言中用pid_t类型表示,其实就是一个非负整数
进程的状态:有初始、就绪、运行、阻塞、挂起、停止等状态
其中初始态为进程准备阶段,常与就绪态 ...
文件相关系统调用
文件相关系统调用open/close函数open/close函数是系统调用中用来打开和关闭文件的函数
函数原型
1234#include <fcntl.h>int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);int close(int fd);
常用flags
flags
explain
O_RDONLY
只读打开
O_WRONLY
只写打开
O_RDWR
读写
O_APPEND
追加
O_CREAT
创建
O_EXCL
文件是否存在
O_TRUNC
截断
O_NONBLOCK
非阻塞
返回值
成功: 打开文件所得到对应的文件描述符(int)
失败: -1, 设置errno
常见错误
打开文件不存在
以写方式打开只读文件(打开文件没有相应权限)
以只写方式打开目录
e.g.
12345678910111213#include <stdio.h>#in ...