Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
作为二进制数组的GCC内联程序集_C_Gcc_Inline Assembly - Fatal编程技术网

作为二进制数组的GCC内联程序集

作为二进制数组的GCC内联程序集,c,gcc,inline-assembly,C,Gcc,Inline Assembly,GCC中是否有任何方法将内联\uuuu asm\uuuu表示为char[]数组?我想要一些像: void my_func(); char my_code[] = { __asm__("callq %0" :: "r" (my_func)) }; 稍后的my_code将用作运行时修补程序,即 void another_function(); mprotect(another_function, getpagesize(), PROT_WRITE | PROT_READ | PROT_E

GCC中是否有任何方法将内联
\uuuu asm\uuuu
表示为
char[]
数组?我想要一些像:

void my_func();

char my_code[] = {
    __asm__("callq %0" :: "r" (my_func))
};
稍后的
my_code
将用作运行时修补程序,即

void another_function();
mprotect(another_function, getpagesize(), PROT_WRITE | PROT_READ | PROT_EXEC);
memcpy(another_function + offset, my_code, sizeof(my_code));

有什么想法吗?

你可以定义一个函数,编译它,然后得到它的源代码

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>

void my_func(void) {}

extern void my_code(void);
extern void my_code_end(void);

__attribute__((__used__)) static void _my_code(void) {
        asm volatile(
                ".globl my_code\n"
                "my_code:\n"
                "  callq *%0\n"
                "  nop\n"
                "  ret\n"
                ".globl my_code_end\n"
                "my_code_end:\n"
                :: "r" (my_func)
        );
}

int main() {
        size_t my_code_len = (uintptr_t)my_code_end - (uintptr_t)my_code;
        const unsigned char *arr = (const char*)my_code;
        printf("my_code[%zu]=", my_code_len);
        for (size_t i = 0; i < my_code_len; ++i) {
                printf("%02x", arr[i]);
        }
        printf("\n");
        return 0;
}
我们可以从组件输出中检查它是否正常:

$ objdump -D ./a.out
...
0000000000000727 <my_code>:
 727:   ff d0                   callq  *%rax
 729:   90                      nop
 72a:   c3                      retq   
...
$objdump-D./a.out
...
0000000000000727 :
727:ff d0 callq*%rax
729:90不
72a:c3 retq
...

你可以定义一个函数,编译它,然后得到它的源代码

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>

void my_func(void) {}

extern void my_code(void);
extern void my_code_end(void);

__attribute__((__used__)) static void _my_code(void) {
        asm volatile(
                ".globl my_code\n"
                "my_code:\n"
                "  callq *%0\n"
                "  nop\n"
                "  ret\n"
                ".globl my_code_end\n"
                "my_code_end:\n"
                :: "r" (my_func)
        );
}

int main() {
        size_t my_code_len = (uintptr_t)my_code_end - (uintptr_t)my_code;
        const unsigned char *arr = (const char*)my_code;
        printf("my_code[%zu]=", my_code_len);
        for (size_t i = 0; i < my_code_len; ++i) {
                printf("%02x", arr[i]);
        }
        printf("\n");
        return 0;
}
我们可以从组件输出中检查它是否正常:

$ objdump -D ./a.out
...
0000000000000727 <my_code>:
 727:   ff d0                   callq  *%rax
 729:   90                      nop
 72a:   c3                      retq   
...
$objdump-D./a.out
...
0000000000000727 :
727:ff d0 callq*%rax
729:90不
72a:c3 retq
...

如果
\u my\u code
包含GCC添加的序言,该怎么办?我在
\u my\u code
中声明
my\u code
,因此如果它确实包含任何序言,它将位于
my\u code
之前。可能应该重构一点,这样它更具可读性。@ivaigult和Kamil:因为您在内联asm中使用了
.globl my_code
等,所以请将它放在全局范围内,而不是放在另一个名称类似的函数中。实际上调用该函数是不安全的(因为它会在不通知编译器的情况下关闭红色区域)。哦,等等,您确实需要从
\u my\u code
复制到
my\u code\u end
,以获取将
my\u func
放入asm选择的寄存器的指令。如果它使用RIP相对LEA(PIE或共享库)而不是绝对的
mov eax,imm32
(非PIE可执行),那么将指令复制到同一个程序中的其他地方会改变地址。如果
\u my_code
包含GCC添加的序言怎么办?我在
\u my_code
中声明
my_code
,因此,如果它确实包含任何序言,那么它将在
my_code
之前。可能应该重构一点,这样它更具可读性。@ivaigult和Kamil:因为您在内联asm中使用了
.globl my_code
等,所以请将它放在全局范围内,而不是放在另一个名称类似的函数中。实际上调用该函数是不安全的(因为它会在不通知编译器的情况下关闭红色区域)。哦,等等,您确实需要从
\u my\u code
复制到
my\u code\u end
,以获取将
my\u func
放入asm选择的寄存器的指令。如果它使用RIP相对LEA(PIE或共享库)而不是绝对
mov eax、imm32
(非PIE可执行文件)来执行此操作,则将指令复制到同一程序中的其他位置将更改地址。