리눅스 시스템 호출이나 표준 C 라이브러리 함수 중 하나를 사용하지 않고 C 문자열을 출력하는 간단한 프로그램을 작성하려고합니다. 이것은 학습 목적으로 만 사용되며, 프로덕션 환경에서는 절대로 그렇게하지 않을 것입니다.인라인 어셈블리 - 로컬 char * 변수에 액세스 - gcc
먼저 내 시스템 정보 :
[[email protected] sandbox-print_chars]$ uname -a
Linux fedora.laptop 2.6.35.14-106.fc14.i686.PAE #1 SMP Wed Nov 23 13:39:51 UTC 2011 i686 i686 i386 GNU/Linux
[[email protected] sandbox-print_chars]$ gcc --version
gcc (GCC) 4.5.1 20100924 (Red Hat 4.5.1-4)
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
다음 코드 :
#include <unistd.h>
#include <sys/syscall.h>
void main()
{
char *str = "Hello World";
while(*(str) != '\0') {
//printf("%c", *(str++));
//syscall(__NR_write, 1, *(str++), 1);
__asm__("movl %0, %%ecx" :"=c" (str));
__asm__("movl $0X4, %eax");
__asm__("movl $0X1, %ebx");
__asm__("movl $0X1, %edx");
__asm__("int $0X80");
str++;
}
return;
}
다음 메이크 파일로 컴파일 :
all: sandbox_c
sandbox_c: sandbox.c
gcc -Wall -o sandbox_c ./sandbox.c
gcc -S -Wall -o sandbox_c.asm ./sandbox.c
상황이 잘 컴파일, 난 그냥 질수는 얻을 일을 얻으려면 구문을 올바르게 사용하십시오. 귀하의 수정 사항을 크게 평가하지만, 당신이 또한 당신이 위대한 될 솔루션을 얻은 방법을 가르쳐 줄 수 있다면.
[[email protected] sandbox-print_chars]$ gdb ./sandbox_c
GNU gdb (GDB) Fedora (7.2-52.fc14)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/mehoggan/Code/Assembly/sandbox/sandbox-print_chars/sandbox_c...done.
(gdb) break sandbox.c:8
Breakpoint 1 at 0x80483a2: file ./sandbox.c, line 8.
(gdb) run
Starting program: /home/mehoggan/Code/Assembly/sandbox/sandbox-print_chars/sandbox_c
Breakpoint 1, main() at ./sandbox.c:8
8 while(*(str) != '\0') {
Missing separate debuginfos, use: debuginfo-install glibc-2.13-2.i686
(gdb) step
11 __asm__("movl %0, %%ecx" :"=c" (str));
(gdb) info registers
eax 0x48 72
ecx 0x34092fad 873017261
edx 0x1 1
ebx 0x567ff4 5668852
esp 0xbffff2a4 0xbffff2a4
ebp 0xbffff2b8 0xbffff2b8
esi 0x0 0
edi 0x0 0
eip 0x80483a4 0x80483a4 <main+16>
eflags 0x200206 [ PF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) step
12 __asm__("movl $0X4, %eax");
(gdb) info registers
eax 0x48 72
ecx 0x34092fad 873017261
edx 0x1 1
ebx 0x34092fad 873017261
esp 0xbffff2a4 0xbffff2a4
ebp 0xbffff2b8 0xbffff2b8
esi 0x0 0
edi 0x0 0
eip 0x80483ab 0x80483ab <main+23>
eflags 0x200206 [ PF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) step
13 __asm__("movl $0X1, %ebx");
(gdb) info registers
eax 0x4 4
ecx 0x34092fad 873017261
edx 0x1 1
ebx 0x34092fad 873017261
esp 0xbffff2a4 0xbffff2a4
ebp 0xbffff2b8 0xbffff2b8
esi 0x0 0
edi 0x0 0
eip 0x80483b0 0x80483b0 <main+28>
eflags 0x200206 [ PF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) step
14 __asm__("movl $0X1, %edx");
(gdb) info registers
eax 0x4 4
ecx 0x34092fad 873017261
edx 0x1 1
ebx 0x1 1
esp 0xbffff2a4 0xbffff2a4
ebp 0xbffff2b8 0xbffff2b8
esi 0x0 0
edi 0x0 0
eip 0x80483b5 0x80483b5 <main+33>
eflags 0x200206 [ PF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) step
15 __asm__("int $0X80");
(gdb) info registers
eax 0x4 4
ecx 0x34092fad 873017261
edx 0x1 1
ebx 0x1 1
esp 0xbffff2a4 0xbffff2a4
ebp 0xbffff2b8 0xbffff2b8
esi 0x0 0
edi 0x0 0
eip 0x80483ba 0x80483ba <main+38>
eflags 0x200206 [ PF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) step
16 str++;
(gdb) info registers
eax 0xfffffff2 -14
ecx 0x34092fad 873017261
edx 0x1 1
ebx 0x1 1
esp 0xbffff2a4 0xbffff2a4
ebp 0xbffff2b8 0xbffff2b8
esi 0x0 0
edi 0x0 0
eip 0x80483bc 0x80483bc <main+40>
eflags 0x200206 [ PF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
실제로 프로그램을 x86 대상으로 제한하고 싶지 않으면 프로덕션 코드에서 절대 수행하지 마십시오. 모든 사람들이 같은 방법으로 시스템 콜을하는 것은 아니며, 확실히 동일한 지시 사항을 사용하지 않습니다! – ams