我不小心在该.data部分中编写了我的汇编代码。我编译并执行了它。该程序在Linux下正常运行5.4.0-53-generic,即使我没有指定就像一面旗帜execstack。
之后,我在 Linux 下执行了该程序5.9.0-050900rc5-generic。该程序得到了SIGSEGV。我通过阅读检查了虚拟内存权限/proc/$pid/maps。事实证明,该部分不可执行。
我认为 Linux 上有一个配置可以管理该权限。但我不知道在哪里可以找到。
ammarfaizi2@integral:/tmp$ uname -r
5.4.0-53-generic
ammarfaizi2@integral:/tmp$ cat test.asm
[section .data]
global _start
_start:
mov eax, 60
xor edi, edi
syscall
ammarfaizi2@integral:/tmp$ nasm --version
NASM version 2.14.02
ammarfaizi2@integral:/tmp$ nasm -felf64 test.asm -o test.o
ammarfaizi2@integral:/tmp$ ld test.o -o test
ammarfaizi2@integral:/tmp$ ./test
ammarfaizi2@integral:/tmp$ echo $?
0
ammarfaizi2@integral:/tmp$ md5sum test
7ffff5fd44e6ff0a278e881732fba525 test
ammarfaizi2@integral:/tmp$
Run Code Online (Sandbox Code Playgroud)
## Debug
gef? shell …Run Code Online (Sandbox Code Playgroud) 我刚刚浏览了Linux内核源代码树并阅读了文件tools/include/nolibc/nolibc.h。
我syscall在这个文件中看到了 use %r8,%r9以及%r10在 clobber 列表中。
还有一条评论说:
rcx 和 r8..r11 可能会被破坏,其他的则被保留。
据我所知,syscall只有 clobbers%rax和%rcx(%r11和记忆)。
有没有syscall真实%r8的例子%r9?%r10
我试图在 Linux 上诊断用 C 编写的应用程序中的错误。原来这个bug是由于在父进程中句柄仍然打开时在子进程中忘记 引起的。fcloseFILE *
文件操作只是read. 没有写操作。
该应用程序正在运行Linux 5.4.0-58-generic。在这种情况下,错误发生了。
该应用程序正在运行Linux 5.10.0-051000-generic。在这种情况下,没有错误,这正是我所期望的。
fork如果fclose子进程中没有,则父进程执行随机数的系统调用。
我完全知道忘记 fclose会导致内存泄漏,但是:
exit(3)不是_exit(2)。fclose会影响父进程?这是一个 Linux 内核错误,已在5.4. 然而我没有证据,但我的测试向我证明了这一点。
我已经能够通过fclose在退出之前调用子进程来修复这个应用程序错误。但是,我想知道在这种情况下实际发生了什么。所以我的问题是如何fclose在子进程中忘记影响父进程?
fclose在于子进程。test2.c 不会fclose在子进程中调用。123123123
123123123
123123123
123123123
123123123 …Run Code Online (Sandbox Code Playgroud) 我正在用 Assembly 编写一个简单的程序来模拟缓冲区溢出。缓冲区只是从 512 字节堆栈中分配的内存,然后read()使用来自 stdin fd 的 4096 字节调用系统调用。
当我在 GDB 之外执行有效负载时,缓冲区溢出工作正常。但是当我在 GDB 中时,系统调用read()返回EFAULT.
在这种情况下,我们的缓冲区溢出应该替换返回地址并使%rip到达secret_func。
为什么在这种情况下缓冲区溢出在 GDB 中不起作用?
.section .rodata
str1:
.ascii "Enter the input: "
str2:
.ascii "\nYou find a secret function!\n"
str_end:
.section .text
.global _start
_start:
xorl %ebp, %ebp
andq $-16, %rsp
callq main
_exit:
movl %eax, %edi
movl $60, %eax
syscall
main:
subq $512, %rsp
movl $1, %eax
movl $1, %edi …Run Code Online (Sandbox Code Playgroud) 我试图用rep movsb指令创建我的 memcpy 代码。当优化被禁用时,它适用于任何尺寸。但是,当我启用优化时,它没有按预期工作。
我从Intel® 64 and IA-32 Architectures Optimization Reference Manual section 3.7.6 中阅读了有关 memcpy 的增强 movsb 。我来到了 libc 源代码,我看到 libc 的默认 memcpy 使用 SSE 而不是movsb.
因此,我想比较memcpy 的SSE 指令和rep movsb之间的性能。但是现在,我发现它有些不对劲。
#include <stdio.h>
#include <string.h>
inline static void *my_memcpy(
register void *dest,
register const void *src,
register size_t n
) {
__asm__ volatile(
"mov %0, %%rdi;"
"mov %1, …Run Code Online (Sandbox Code Playgroud) 鉴于:
#include <string.h>
bool test_data(void *data)
{
return memcmp(data, "abcd", 4) == 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器可以将其优化为:
test_data:
cmpl $1684234849, (%rdi)
sete %al
ret
Run Code Online (Sandbox Code Playgroud)
这很好。
但如果我使用我自己的memcmp()(而不是来自<string.h>),编译器无法将其优化为单个cmpl指令。相反,它这样做:
test_data:
cmpl $1684234849, (%rdi)
sete %al
ret
Run Code Online (Sandbox Code Playgroud)
test_data:
cmpb $97, (%rdi)
jne .L5
cmpb $98, 1(%rdi)
jne .L5
cmpb $99, 2(%rdi)
jne .L5
cmpb $100, 3(%rdi)
sete %al
ret
.L5:
xorl %eax, %eax
ret
Run Code Online (Sandbox Code Playgroud)
链接: https: //godbolt.org/z/Kfhchr45a
以下代码部分的目的是轮询套接字 fd-set,如果数据(ssl 加密)可用,则读取它并通过 openssl 库解密。底层传输层是 TCP Stream,因此数据以流的形式出现(而不是数据包)。
现在,如果从对等方快速连续发送了多个数据包(假设有 2 个长度为 85 字节的数据包),那么 TCP 接收将返回同一缓冲区中的两个数据包,接收的字节数为 170。因此,我们有一个携带 2 个 ssl 加密数据包(或 n 个数据包)的缓冲区。对于 ssl 解密,我们需要调用 BIO_write() 将缓冲区写入 ssl_bio,然后调用 ssl_read() 来检索解密的缓冲区。但是,尽管 BIO_write() 正在向 bio 中写入 170 个字节,但 ssl_read() 似乎只返回一个解密的数据包(43 个字节)。没有返回错误。如何知道 bio 中是否还有未处理的字节。有什么出路吗或者代码中有什么错误?
当在 tcp recv() 中接收到单个数据包时,代码工作正常。
int iReadyFds = poll( PollFdSet, iFdCount, iTimeout);
for(iFdIndx = 0; iFdIndx < (iFdCount) && (iReadyFds>0); ++iFdIndx)
{
if((PollFdSet[iFdIndx].events == 0) ||
(PollFdSet[iFdIndx].fd == 0) ||
(PollFdSet[iFdIndx].revents != POLLIN)
)
{
continue;
}
/* we have data to …Run Code Online (Sandbox Code Playgroud) 考虑以下:
ammarfaizi2@integral:/tmp$ vi test.c
ammarfaizi2@integral:/tmp$ cat test.c
extern void use_buffer(void *buf);
void a_func(void)
{
char buffer[4096];
use_buffer(buffer);
}
__asm__("emit_mov_rbp_to_rsp:\n\tmovq %rbp, %rsp");
ammarfaizi2@integral:/tmp$ clang -Wall -Wextra -c -O3 -fno-omit-frame-pointer test.c -o test.o
ammarfaizi2@integral:/tmp$ objdump -d test.o
test.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <emit_mov_rbp_to_rsp>:
0: 48 89 ec mov %rbp,%rsp
3: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)
a: 00 00 00
d: 0f 1f 00 nopl (%rax)
0000000000000010 <a_func>:
10: 55 push %rbp
11: 48 …Run Code Online (Sandbox Code Playgroud) 我尝试更换malloc(3)/ calloc(3)/ realloc(3)/free(3)通过LD_PRELOAD环境变量。我尝试使用静态链接的自定义函数,它们工作得很好。
但是,当我将它作为共享库附加到 时LD_PRELOAD,它总是会导致段错误。
mmap(2)和munmap(2)syscall for malloc(3)and free(3)。calloc(3)只是对malloc(3)乘法溢出检查的调用。realloc(3)电话malloc(3),然后复制旧的数据到新分配的内存和取消映射旧内存。我完全意识到mmap每次malloc调用时总是使用是一个坏主意,尤其是对于性能而言。我只想知道为什么我的方法不起作用。
ammarfaizi2@integral:~$ gcc -shared mem.c -O3 -o my_mem.so
ammarfaizi2@integral:~$ LD_PRELOAD=$(pwd)/my_mem.so ls
Segmentation fault (core dumped)
ammarfaizi2@integral:~$ LD_PRELOAD=$(pwd)/my_mem.so cat
Segmentation fault (core dumped)
ammarfaizi2@integral:~$ LD_PRELOAD=$(pwd)/my_mem.so w
Segmentation fault (core …Run Code Online (Sandbox Code Playgroud) 根据手册页https://linux.die.net/man/3/pthread_mutex_lock
互斥锁引用的互斥锁对象应通过调用 pthread_mutex_lock() 锁定。如果互斥锁已被锁定,则调用线程应阻塞,直到互斥锁可用。
我有一个带线程的程序。这是程序流程:
pthread_mutex_lock一个循环内。pthread_mutex_unlock,线程应该突然获得锁。问题是,在第 3 点,线程不会在主进程释放锁后立即获得锁。主进程pthread_mutex_lock在下一个循环周期(在第 4 点)调用时首先获得它。
如何处理这种情况?
如何让线程在主进程释放锁后立即获得锁?
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
void *
my_thread(void *p)
{
(void)p;
while (1) {
pthread_mutex_lock(&my_mutex);
printf("The thread is holding the lock...\n");
sleep(1);
pthread_mutex_unlock(&my_mutex); …Run Code Online (Sandbox Code Playgroud)