时间从来不语,却回答了很多问题


本文只是用来熟悉C++的面向对象语法,前提是学过别的

内容概括

类和对象

函数可在类或结构体中直接定义,也可以只进行声明,在类或结构体外再用命名空间进行定义。

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
// 在内部定义
class Box {
public:
double length; // 长度
double breadth; // 宽度
double height; // 高度

double getVolume(void) {
return length * breadth * height;
}
};

// 在外部定义
class Box {
public:
double length; // 长度
double breadth; // 宽度
double height; // 高度
// 成员函数声明
double get(void);
void set( double len, double bre, double hei );
};

// 成员函数定义
double Box::get(void) {
return length * breadth * height;
}

void Box::set( double len, double bre, double hei) {
length = len;
breadth = bre;
height = hei;
}

其他成员函数:

阅读此文


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
/*

This file contains definitions used by the Hex-Rays decompiler output.
It has type definitions and convenience macros to make the
output more readable.

Copyright (c) 2007-2011 Hex-Rays

*/

#if defined(__GNUC__)
typedef long long ll;
typedef unsigned long long ull;
#define __int64 long long
#define __int32 int
#define __int16 short
#define __int8 char
#define MAKELL(num) num ## LL
#define FMT_64 "ll"
#elif defined(_MSC_VER)
typedef __int64 ll;
typedef unsigned __int64 ull;
#define MAKELL(num) num ## i64
#define FMT_64 "I64"
#elif defined (__BORLANDC__)
typedef __int64 ll;
typedef unsigned __int64 ull;
#define MAKELL(num) num ## i64
#define FMT_64 "L"
#else
#error "unknown compiler"
#endif
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned long ulong;

typedef char int8;
typedef signed char sint8;
typedef unsigned char uint8;
typedef short int16;
typedef signed short sint16;
typedef unsigned short uint16;
typedef int int32;
typedef signed int sint32;
typedef unsigned int uint32;
typedef ll int64;
typedef ll sint64;
typedef ull uint64;

// Partially defined types:
#define _BYTE uint8
#define _WORD uint16
#define _DWORD uint32
#define _QWORD uint64
#if !defined(_MSC_VER)
#define _LONGLONG __int128
#endif

#ifndef _WINDOWS_
typedef int8 BYTE;
typedef int16 WORD;
typedef int32 DWORD;
typedef int32 LONG;
#endif
typedef int64 QWORD;
#ifndef __cplusplus
typedef int bool; // we want to use bool in our C programs
#endif

// Some convenience macros to make partial accesses nicer
// first unsigned macros:
#define LOBYTE(x) (*((_BYTE*)&(x))) // low byte
#define LOWORD(x) (*((_WORD*)&(x))) // low word
#define LODWORD(x) (*((_DWORD*)&(x))) // low dword
#define HIBYTE(x) (*((_BYTE*)&(x)+1))
#define HIWORD(x) (*((_WORD*)&(x)+1))
#define HIDWORD(x) (*((_DWORD*)&(x)+1))
#define BYTEn(x, n) (*((_BYTE*)&(x)+n))
#define WORDn(x, n) (*((_WORD*)&(x)+n))
#define BYTE1(x) BYTEn(x, 1) // byte 1 (counting from 0)
#define BYTE2(x) BYTEn(x, 2)
#define BYTE3(x) BYTEn(x, 3)
#define BYTE4(x) BYTEn(x, 4)
#define BYTE5(x) BYTEn(x, 5)
#define BYTE6(x) BYTEn(x, 6)
#define BYTE7(x) BYTEn(x, 7)
#define BYTE8(x) BYTEn(x, 8)
#define BYTE9(x) BYTEn(x, 9)
#define BYTE10(x) BYTEn(x, 10)
#define BYTE11(x) BYTEn(x, 11)
#define BYTE12(x) BYTEn(x, 12)
#define BYTE13(x) BYTEn(x, 13)
#define BYTE14(x) BYTEn(x, 14)
#define BYTE15(x) BYTEn(x, 15)
#define WORD1(x) WORDn(x, 1)
#define WORD2(x) WORDn(x, 2) // third word of the object, unsigned
#define WORD3(x) WORDn(x, 3)
#define WORD4(x) WORDn(x, 4)
#define WORD5(x) WORDn(x, 5)
#define WORD6(x) WORDn(x, 6)
#define WORD7(x) WORDn(x, 7)

// now signed macros (the same but with sign extension)
#define SLOBYTE(x) (*((int8*)&(x)))
#define SLOWORD(x) (*((int16*)&(x)))
#define SLODWORD(x) (*((int32*)&(x)))
#define SHIBYTE(x) (*((int8*)&(x)+1))
#define SHIWORD(x) (*((int16*)&(x)+1))
#define SHIDWORD(x) (*((int32*)&(x)+1))
#define SBYTEn(x, n) (*((int8*)&(x)+n))
#define SWORDn(x, n) (*((int16*)&(x)+n))
#define SBYTE1(x) SBYTEn(x, 1)
#define SBYTE2(x) SBYTEn(x, 2)
#define SBYTE3(x) SBYTEn(x, 3)
#define SBYTE4(x) SBYTEn(x, 4)
#define SBYTE5(x) SBYTEn(x, 5)
#define SBYTE6(x) SBYTEn(x, 6)
#define SBYTE7(x) SBYTEn(x, 7)
#define SBYTE8(x) SBYTEn(x, 8)
#define SBYTE9(x) SBYTEn(x, 9)
#define SBYTE10(x) SBYTEn(x, 10)
#define SBYTE11(x) SBYTEn(x, 11)
#define SBYTE12(x) SBYTEn(x, 12)
#define SBYTE13(x) SBYTEn(x, 13)
#define SBYTE14(x) SBYTEn(x, 14)
#define SBYTE15(x) SBYTEn(x, 15)
#define SWORD1(x) SWORDn(x, 1)
#define SWORD2(x) SWORDn(x, 2)
#define SWORD3(x) SWORDn(x, 3)
#define SWORD4(x) SWORDn(x, 4)
#define SWORD5(x) SWORDn(x, 5)
#define SWORD6(x) SWORDn(x, 6)
#define SWORD7(x) SWORDn(x, 7)


// Helper functions to represent some assembly instructions.

#ifdef __cplusplus

// Fill memory block with an integer value
inline void memset32(void *ptr, uint32 value, int count)
{
uint32 *p = (uint32 *)ptr;
for ( int i=0; i < count; i++ )
*p++ = value;
}

// Generate a reference to pair of operands
template<class T> int16 __PAIR__( int8 high, T low) { return ((( int16)high) << sizeof(high)*8) | uint8(low); }
template<class T> int32 __PAIR__( int16 high, T low) { return ((( int32)high) << sizeof(high)*8) | uint16(low); }
template<class T> int64 __PAIR__( int32 high, T low) { return ((( int64)high) << sizeof(high)*8) | uint32(low); }
template<class T> uint16 __PAIR__(uint8 high, T low) { return (((uint16)high) << sizeof(high)*8) | uint8(low); }
template<class T> uint32 __PAIR__(uint16 high, T low) { return (((uint32)high) << sizeof(high)*8) | uint16(low); }
template<class T> uint64 __PAIR__(uint32 high, T low) { return (((uint64)high) << sizeof(high)*8) | uint32(low); }

// rotate left
template<class T> T __ROL__(T value, uint count)
{
const uint nbits = sizeof(T) * 8;
count %= nbits;

T high = value >> (nbits - count);
value <<= count;
value |= high;
return value;
}

// rotate right
template<class T> T __ROR__(T value, uint count)
{
const uint nbits = sizeof(T) * 8;
count %= nbits;

T low = value << (nbits - count);
value >>= count;
value |= low;
return value;
}

// carry flag of left shift
template<class T> int8 __MKCSHL__(T value, uint count)
{
const uint nbits = sizeof(T) * 8;
count %= nbits;

return (value >> (nbits-count)) & 1;
}

// carry flag of right shift
template<class T> int8 __MKCSHR__(T value, uint count)
{
return (value >> (count-1)) & 1;
}

// sign flag
template<class T> int8 __SETS__(T x)
{
if ( sizeof(T) == 1 )
return int8(x) < 0;
if ( sizeof(T) == 2 )
return int16(x) < 0;
if ( sizeof(T) == 4 )
return int32(x) < 0;
return int64(x) < 0;
}

// overflow flag of subtraction (x-y)
template<class T, class U> int8 __OFSUB__(T x, U y)
{
if ( sizeof(T) < sizeof(U) )
{
U x2 = x;
int8 sx = __SETS__(x2);
return (sx ^ __SETS__(y)) & (sx ^ __SETS__(x2-y));
}
else
{
T y2 = y;
int8 sx = __SETS__(x);
return (sx ^ __SETS__(y2)) & (sx ^ __SETS__(x-y2));
}
}

// overflow flag of addition (x+y)
template<class T, class U> int8 __OFADD__(T x, U y)
{
if ( sizeof(T) < sizeof(U) )
{
U x2 = x;
int8 sx = __SETS__(x2);
return ((1 ^ sx) ^ __SETS__(y)) & (sx ^ __SETS__(x2+y));
}
else
{
T y2 = y;
int8 sx = __SETS__(x);
return ((1 ^ sx) ^ __SETS__(y2)) & (sx ^ __SETS__(x+y2));
}
}

// carry flag of subtraction (x-y)
template<class T, class U> int8 __CFSUB__(T x, U y)
{
int size = sizeof(T) > sizeof(U) ? sizeof(T) : sizeof(U);
if ( size == 1 )
return uint8(x) < uint8(y);
if ( size == 2 )
return uint16(x) < uint16(y);
if ( size == 4 )
return uint32(x) < uint32(y);
return uint64(x) < uint64(y);
}

// carry flag of addition (x+y)
template<class T, class U> int8 __CFADD__(T x, U y)
{
int size = sizeof(T) > sizeof(U) ? sizeof(T) : sizeof(U);
if ( size == 1 )
return uint8(x) > uint8(x+y);
if ( size == 2 )
return uint16(x) > uint16(x+y);
if ( size == 4 )
return uint32(x) > uint32(x+y);
return uint64(x) > uint64(x+y);
}

#else
// The following definition is not quite correct because it always returns
// uint64. The above C++ functions are good, though.
#define __PAIR__(high, low) (((uint64)(high)<<sizeof(high)*8) | low)
// For C, we just provide macros, they are not quite correct.
#define __ROL__(x, y) __rotl__(x, y) // Rotate left
#define __ROR__(x, y) __rotr__(x, y) // Rotate right
#define __CFSHL__(x, y) invalid_operation // Generate carry flag for (x<<y)
#define __CFSHR__(x, y) invalid_operation // Generate carry flag for (x>>y)
#define __CFADD__(x, y) invalid_operation // Generate carry flag for (x+y)
#define __CFSUB__(x, y) invalid_operation // Generate carry flag for (x-y)
#define __OFADD__(x, y) invalid_operation // Generate overflow flag for (x+y)
#define __OFSUB__(x, y) invalid_operation // Generate overflow flag for (x-y)
#endif

// No definition for rcl/rcr because the carry flag is unknown
#define __RCL__(x, y) invalid_operation // Rotate left thru carry
#define __RCR__(x, y) invalid_operation // Rotate right thru carry
#define __MKCRCL__(x, y) invalid_operation // Generate carry flag for a RCL
#define __MKCRCR__(x, y) invalid_operation // Generate carry flag for a RCR
#define __SETP__(x, y) invalid_operation // Generate parity flag for (x-y)

// In the decompilation listing there are some objects declarared as _UNKNOWN
// because we could not determine their types. Since the C compiler does not
// accept void item declarations, we replace them by anything of our choice,
// for example a char:

#define _UNKNOWN char

#ifdef _MSC_VER
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#endif
阅读此文


PWN环境搭建

  1. 新建Ubuntu虚拟机

  2. 安装python与pip(可以用python3)

  3. 安装 git,gdb 和 gdb-multiarch,同时安装 binfmt 用来识别文件类型

    1
    2
    sudo apt install git gdb gdb-multiarch
    sudo apt install "binfmt*"
  4. 安装 gdb 的插件 pwndbg(或者 gef 等 gdb plugin)

    1
    2
    3
    git clone https://github.com/pwndbg/pwndbg
    cd pwndbg
    ./setup.sh

    如果安装超时出错参考:Ubuntu安装pwndbg超时处理( Read timed out)

  5. 安装pwntools

    1
    pip install pwntools
  6. 如果要在64位linux下运行32位程序,需要装multilib(测试ubuntu22.04 wsl2不需要)

    1
    sudo apt install gcc-multilib
  7. ~/.local/bin放入环境变量(pwntools自带一些工具)

    1
    2
    # 可以把这一行放入~/.zshrc或~/.bashrc
    export PATH="/home/ylcao/.local/bin/:$PATH"
  8. Libc偏移搜索工具lieanu/LibcSearcher: glibc offset search for ctf.

  9. 更新libc数据库

    1. 删除clone的文件夹里的libc-database,然后

      1
      git clone https://github.com/niklasb/libc-database.git && cd libc-database && ./get ubuntu

使用peda插件(pwndbg安装出现很多问题)

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
# 载入一个文件
$ gdb {file}
-cd:设置工作目录;
-q:安静模式,不打印介绍信息和版本信息;
-d:添加文件查找路径;
-x:从指定文件中执行GDB指令;
-s:设置读取的符号表文件。
# 或者进入gdb后:
file {file}

# 运行/重新运行
r

# 继续运行
c

# 显示源程序代码的内容,包括各行代码所在的行号
l

# 下断点
b <行号>
b <函数名称>
b *<函数名称>
b *<代码地址> d [编号]
b +/-offset # 在当前暂停位置的偏移下断
tbreak # 只作用一次
rbreak regex # 在正则匹配的函数名开头断点 不会一次消失

# 查看断点
i b
# i 用于查看各类信息

# 删除断点
d 断点序号

# 查看栈
stack <行数>

# 针对源代码的单步
n # 步过
s # 步进

# 针对汇编指令的单步
ni
si

# 显示变量的值
p <value>

# 退出
q

# 查看帮助
h

# 反汇编
disass

# 查看各种数据
x/i
x/s
x/b
# 斜杠后加数字表示查看的数量

# 直接回车进行上一步操作


# 使用命令行参数
gdb --args 命令行+参数等

# backtraces查看堆栈调用:
bt # 显示所有的函数调用栈帧的信息,每个帧一行。
bt n # 显示栈定的n个帧信息。
bt -n # 显示栈底的n个帧信息。
bt full # 显示栈中所有帧的完全信息如:函数参数,本地变量
bt full n # 用发同上。
bt full -n #

例子:BUUCTF T2 rip

载入

阅读此文


阅读李忠的《x86汇编语言从实模式到保护模式》时,遇到了要将二进制文件写入VHD文件的问题。Windows环境可以使用随书工具FixVhdWr,在Linux或Mac下可以使用dd工具。

On linux, you may create the vhd file via virtualbox first, and execute the command following to copy the content of the mbr sector into the vhd file. dd if=c05_mbr.bin of=LEARN-ASM.vhd bs=512 count=1 conv=notrunc With the option ‘notrunc’, the size of the output file will not change when it is bigger than the input file’s.

virtual machine - how can we write binary file to a VHD file on mac - Stack Overflow

1
dd if=二进制文件名 of=目标vhd文件 bs=512 count=1 conv=notrunc
阅读此文


post @ 2022-04-08

22.4.8更新

慢慢积累,不定更新

BurpSuite

简单的设置抓包等就不说了,只是记录一些使用方法或技巧。

Intercept响应无拦截

右键-Do intercept-Response to this request

阅读此文


post @ 2022-04-08

一、GUI图形化渗透测试信息收集工具

项目地址:https://github.com/xzajyjs/ThunderSearch

二、一站式解决渗透测试的信息收集任务

项目地址:https://github.com/xzajyjs/SiteScan

三、RDP 渗透测试工具和脚本

项目地址:https://github.com/0x90/rdp-arsenal

四、红队作战中的一些工具分享

阅读此文


先说环境,我的测试手机为Redmi Note 8 Pro,bl锁已解,刷了crDroid Android 11类原生和Magisk 24.3

现在流行的Xposed刷入方法,主要是EdXposed和太极两种玩法。

先安装太极·阳:

太极下载 | 太极

安装好太极Apk后,下载 magisk-taichi-vx.x.x.zip,安装模块到Magisk,打开应用即可激活太极·阳

Xposed框架安装:

先安装EdXposed的Manager,作者是多个人的,更新不是特别勤快

阅读此文


官网:Karabiner-Elements

功能强大,系统级调整

阅读此文


22.8.8更新

相关前言

简单来说因为开发者没有秉持“外部参数皆不可信的原则”进行开发,导致产品满足以下两个条件:

  • 攻击者可以控制要构造的参数
  • 参数带入数据库查询(直接拼接到SQL语句,没有作过滤处理)

SQL注入的常见类型

  • UNION query SQL injection(union查询注入)
  • Boolean-based blind SQL injection(布尔盲注)
  • Error-based SQL injection(基于报错的注入)
  • Time-based blind SQL injection(时间盲注)
  • Stacked queries SQL injection

MySQL一些重要数据库

阅读此文


post @ 2022-04-06

Tmux 是一个终端复用器(terminal multiplexer),非常有用,属于常用的开发工具。

一、Tmux 是什么?

1.1 会话与进程

命令行的典型使用方式是,打开一个终端窗口(terminal window,以下简称”窗口”),在里面输入命令。用户与计算机的这种临时的交互,称为一次”会话”(session) 。

会话的一个重要特点是,窗口与其中启动的进程是连在一起的。打开窗口,会话开始;关闭窗口,会话结束,会话内部的进程也会随之终止,不管有没有运行完。

一个典型的例子就是,SSH 登录远程计算机,打开一个远程窗口执行命令。这时,网络突然断线,再次登录的时候,是找不回上一次执行的命令的。因为上一次 SSH 会话已经终止了,里面的进程也随之消失了。

为了解决这个问题,会话与窗口可以”解绑”:窗口关闭时,会话并不终止,而是继续运行,等到以后需要的时候,再让会话”绑定”其他窗口。

阅读此文
⬆︎TOP