是否可以使用内联汇编块中的系统调用来编写单个字符?如果是这样,怎么样?它应该看起来像这样的"东西":
__asm__ __volatile__
(
" movl $1, %%edx \n\t"
" movl $80, %%ecx \n\t"
" movl $0, %%ebx \n\t"
" movl $4, %%eax \n\t"
" int $0x80 \n\t"
::: "%eax", "%ebx", "%ecx", "%edx"
);
Run Code Online (Sandbox Code Playgroud)
80美元是ascii中的'P',但是没有返回任何内容.
任何建议非常感谢!
我正在Linux上学习x86_64程序集,我遇到了一些我希望可以解决的冲突信息.一方面,我已经读过,对于syscall参数,你会按照rdi,rsi,rdx等顺序使用寄存器.但另一方面,我读过你使用寄存器rbx,rcx,rdx等.一个人告诉我,这是因为ABI的原因,但我并不完全明白这究竟意味着什么.
所以我想我要问的是,为什么这两种格式和哪种格式适合使用?
谢谢!
64位CPU(amd64)在兼容模式下支持32位Intel指令.此外,如果ELF头表示它是32位可执行文件,64位Linux安装允许运行包含32位指令的ELF.
我想知道是否可以在ELF中放置一些汇编指令,在程序中间将CPU切换到32位兼容模式(然后再返回)?如果内核不允许这些汇编指令,我们是否可以通过某种方式让内核将已经运行的进程切换到32位?
这主要是出于好奇心的问题,因为我无法真正看到任何用例.
[bits 32]
global _start
section .data
str_hello db "HelloWorld", 0xa
str_hello_length db $-str_hello
section .text
_start:
mov ebx, 1 ; stdout file descriptor
mov ecx, str_hello ; pointer to string of characters that will be displayed
mov edx, [str_hello_length] ; count outputs Relative addressing
mov eax, 4 ; sys_write
int 0x80 ; linux kernel system call
mov ebx, 0 ; exit status zero
mov eax, 1 ; sys_exit
int 0x80 ; linux kernel system call
Run Code Online (Sandbox Code Playgroud)
这里的基本要点是我需要将hello字符串的长度传递给linux的sys_write系统调用.现在,我很清楚我可以使用EQU,它会工作正常,但我真的想了解这里发生了什么.
所以,基本上当我使用EQU时,它会加载值,这很好.
str_hello_length equ $-str_hello …Run Code Online (Sandbox Code Playgroud) 我正在研究Linux内核,目前我尝试实现自己的系统调用.
在内核代码中,它看起来如下:
asmlinkage long sys_my_syscall()
{
printk("My system call\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我用systemcall()函数调用它可以正常工作,但我找到了另一种方法:
int my_syscall(void)
{
long __res;
__asm__ volatile (
"movl $312, %%eax;"
"int $0x80;"
"movl %%eax, %0;"
: "=m" (__res)
:
: "%eax"
);
if ((unsigned long) (__res) >= (unsigned long) (-125)) {
errno = -(__res);
__res = -1;
}
return (int)(__res);
}
Run Code Online (Sandbox Code Playgroud)
但它返回了价值-14 EFAULT.
我究竟做错了什么?
设置: Linux内核3.4,ARCH x86_64
我编写了一个程序,它应该像for循环一样,打印一串文本一定次数.
这是代码:
global _start
section .data
msg db "Hello World!",10 ; define the message
msgl equ $ - msg ; define message length
; use minimal size of storage space
imax dd 0x00001000 ; defines imax to be big!
section .text
_start:
mov r8, 0x10 ; <s> put imax in r8d, this will be our 'i' </s>
; just attempt 10 iterations
_loop_entry: ; loop entry point
mov eax, 4 ; setup the message to print
mov ebx, …Run Code Online (Sandbox Code Playgroud) 我想在汇编中调用一个系统调用.问题是我做不到mov ecx,rsp.rsp是64位寄存器,ecx是32位寄存器.我想将缓冲区addr作为此系统调用的参数传递.我能做什么?谢谢.
section .data
s0: db "Largest basic function number supported:%s\n",0
s0len: equ $-s0
section .text
global main
extern write
main:
sub rsp, 16
xor eax, eax
cpuid
mov [rsp], ebx
mov [rsp+4], edx
mov [rsp+8], ecx
mov [rsp+12], word 0x0
mov eax, 4
mov ebx, 1
mov ecx, rsp
mov edx, 4
int 80h
mov eax, 4
mov ebx, 1
mov ecx, s0
mov edx, s0len
int 80h
mov eax, 1
int 80h
Run Code Online (Sandbox Code Playgroud) 我正在创建有关缓冲区溢出和堆栈/堆攻击的培训。我正在 Ubuntu 12.04 x86_64机器上工作,想要展示一些有错误的程序示例以及利用这些漏洞的方法。
我试图从迄今为止找到的最基本的 shellcode 开始,即简单的 exit 调用,它应该退出溢出的程序。
因此exitcall.asm:
;exitcall.asm
[SECTION .text]
global _start
_start:
xor ebx,ebx ; zero out ebx, same function as mov ebx,0
mov al, 1 ; exit command to kernel
int 0x80
Run Code Online (Sandbox Code Playgroud)
我从其他教程中得到了这个 asm 文件,但它是为i386架构编写的。接下来要做的是生成一个目标文件并将其设为二进制可执行文件:
# nasm -f elf64 exitcall.asm
# ld -o exitcall exitcall.o
# file exitcall
exitcall: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
# strace ./exitcall
execve("./exitcall", ["./exitcall"], [/* 73 vars */]) …Run Code Online (Sandbox Code Playgroud) 首先,如果有人知道标准 C 库的一个函数,该函数无需查找二进制零即可打印字符串,但需要绘制字符数,请告诉我!
否则,我有这个问题:
void printStringWithLength(char *str_ptr, int n_chars){
asm("mov 4, %rax");//Function number (write)
asm("mov 1, %rbx");//File descriptor (stdout)
asm("mov $str_ptr, %rcx");
asm("mov $n_chars, %rdx");
asm("int 0x80");
return;
}
Run Code Online (Sandbox Code Playgroud)
GCC 将以下错误告知“int”指令:
"Error: operand size mismatch for 'int'"
Run Code Online (Sandbox Code Playgroud)
有人可以告诉我这个问题吗?
我需要获得以下输出:
*
**
***
****
*****
******
*******
********
*********
**********
Run Code Online (Sandbox Code Playgroud)
所以它的10行,而我的星星将从1开始到10。
目前我得到:
**********
***********
************
*************
**************
***************
****************
*****************
******************
*******************
********************
Run Code Online (Sandbox Code Playgroud)
我的代码:
*
**
***
****
*****
******
*******
********
*********
**********
Run Code Online (Sandbox Code Playgroud)
我尝试了又尝试了又尝试了,但是我无法获得所需的东西。
由于所有这些push和,我似乎无法找到一种将行与星线分开的方法pop。
老实说,我对此不太了解。有人告诉我,执行循环需要它们,但是我不确定为什么要在函数star中调用外部循环。
我找不到任何的组合push和pop奏效。我不断得到很多星,或者每行一颗星,或者只有一颗星。
我真的不知道要更改哪些位并保持不变。我能够获得所需的输出,但是输出从未停止增加。
我能够得到从10颗星开始下降到1颗星的输出,但是从来没有我想要的。
我究竟做错了什么?我该怎么办?
assembly ×7
linux ×7
x86-64 ×7
nasm ×4
system-calls ×4
c ×3
gcc ×2
32bit-64bit ×1
64-bit ×1
elf ×1
gdb ×1
linux-kernel ×1
shellcode ×1
x86 ×1
yasm ×1