循环 0xb7 汇编但不会 link
loop 0xb7 assembles but won't link
我正在尝试编译 Debian 上的以下 ASM 代码,但 ld
和 gcc
.
都存在问题
uname -a: Linux kali 4.18.0-kali3-amd64 #1 SMP Debian 4.18.20-2kali2 (2018-11-30) x86_64 GNU/Linux
我从 运行 开始:nasm -f elf shellcode.asm
完成没有任何问题。
GCC 问题...
命令:gcc -m32 -o key shellcode.o
错误:
/usr/bin/ld: shellcode.o: in function `_start':
shellcode.asm:(.text+0x0): multiple definition of `_start'; /usr/lib/gcc/x86_64-linux-gnu/8/../../../../lib32/Scrt1.o:(.text+0x0): first defined here
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/8/../../../../lib32/Scrt1.o: in function `_start':
(.text+0x28): undefined reference to `main'
/usr/bin/ld: shellcode.o: in function `_start':
shellcode.asm:(.text+0xbc): relocation truncated to fit: R_386_PC8 against `*UND*'
collect2: error: ld returned 1 exit status
我也试过 ld
。
命令:ld -m elf_i386 -s -o key shellcode.o
错误...
ld: shellcode.o: in function `_start':
shellcode.asm:(.text+0xbc): relocation truncated to fit: R_386_PC8 against `*UND*'
后者似乎没有那么多错误,并指出 ASM 语法存在问题。
那么我的问题是,这些命令中的哪一个是正确的,我做错了什么?
shellcode.asm
global _start
_start:
xor eax,eax
push eax
push dword 0x76767975
push dword 0x22717172
push dword 0x22737972
push dword 0x77207922
push dword 0x78272079
push dword 0x27277976
push dword 0x77707470
push dword 0x22777272
push dword 0x22277622
push dword 0x79727473
push dword 0x27727377
push dword 0x75747078
push dword 0x70227479
push dword 0x75222073
push dword 0x24747176
push dword 0x74782324
push dword 0x72727320
push dword 0x27762779
push dword 0x20277777
push dword 0x22207573
push dword 0x70247827
push dword 0x70277479
push dword 0x24712379
push dword 0x77742027
push dword 0x76242379
push dword 0x22702270
push dword 0x73762577
push dword 0x24752272
push dword 0x20277172
push dword 0x23712720
push dword 0x72722478
push dword 0x70252723
push esp
pop esi
mov edi,esi
mov edx,edi
cld
mov ecx,0x80
mov ebx,0x41
xor eax,eax
push eax
lodsb
xor eax,ebx
stosb
loop 0xb7
push esp
pop esi
int3
db 0x0a
要使用 gcc 构建,您要定义 _start
而不是 main
,因此您需要使用 -nostdlib
。喜欢gcc -m32 -nostdlib -static -o key shellcode.o
。这将使 gcc 以您手动执行的方式调用 ld
。
loop
仅适用于 rel8 位移,因此它无法从 ld
将其放置在代码段中的更高地址到达绝对地址 0xb7
。
如果你真的想这样做(但你几乎肯定不想),你可以使用dec ecx / jnz 0xb7
,它将使用 jcc rel32
编码,因此可以通过 EIP + rel32
到达任何绝对地址。或者使用 linker 脚本在非常低的虚拟地址 link TEXT 段,以便 loop rel8
可以到达。
(但无论哪种方式都不是 position-independent。通常 shellcode 应该在被注入到未知地址后工作。如果你真的想跳转到 position-independent shellcode 中的绝对地址,比如要触发特定的页面错误(?),您需要寄存器中的地址并使用 jmp eax
)
但您更有可能想跳转到代码中的其他地方,而不是某些低绝对地址。 在您的分支目标上放置一个标签并使用 dec ecx / jnz label
。 (或者使用 loop
指令,因为您可能正在针对 code-size 进行优化,而不管它是否缓慢。)
如果您从某处借用此代码,可能是在 loop 0xb7
设置 rel8
位移值的汇编器中。或者可能是 NASM 与 org 0x0
和 BITS 32
制作了一个平面二进制文件?但是如果你想分支回到这段代码中的某个地方,使用标签会更有意义。
我正在尝试编译 Debian 上的以下 ASM 代码,但 ld
和 gcc
.
uname -a: Linux kali 4.18.0-kali3-amd64 #1 SMP Debian 4.18.20-2kali2 (2018-11-30) x86_64 GNU/Linux
我从 运行 开始:nasm -f elf shellcode.asm
完成没有任何问题。
GCC 问题...
命令:gcc -m32 -o key shellcode.o
错误:
/usr/bin/ld: shellcode.o: in function `_start':
shellcode.asm:(.text+0x0): multiple definition of `_start'; /usr/lib/gcc/x86_64-linux-gnu/8/../../../../lib32/Scrt1.o:(.text+0x0): first defined here
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/8/../../../../lib32/Scrt1.o: in function `_start':
(.text+0x28): undefined reference to `main'
/usr/bin/ld: shellcode.o: in function `_start':
shellcode.asm:(.text+0xbc): relocation truncated to fit: R_386_PC8 against `*UND*'
collect2: error: ld returned 1 exit status
我也试过 ld
。
命令:ld -m elf_i386 -s -o key shellcode.o
错误...
ld: shellcode.o: in function `_start':
shellcode.asm:(.text+0xbc): relocation truncated to fit: R_386_PC8 against `*UND*'
后者似乎没有那么多错误,并指出 ASM 语法存在问题。
那么我的问题是,这些命令中的哪一个是正确的,我做错了什么?
shellcode.asm
global _start
_start:
xor eax,eax
push eax
push dword 0x76767975
push dword 0x22717172
push dword 0x22737972
push dword 0x77207922
push dword 0x78272079
push dword 0x27277976
push dword 0x77707470
push dword 0x22777272
push dword 0x22277622
push dword 0x79727473
push dword 0x27727377
push dword 0x75747078
push dword 0x70227479
push dword 0x75222073
push dword 0x24747176
push dword 0x74782324
push dword 0x72727320
push dword 0x27762779
push dword 0x20277777
push dword 0x22207573
push dword 0x70247827
push dword 0x70277479
push dword 0x24712379
push dword 0x77742027
push dword 0x76242379
push dword 0x22702270
push dword 0x73762577
push dword 0x24752272
push dword 0x20277172
push dword 0x23712720
push dword 0x72722478
push dword 0x70252723
push esp
pop esi
mov edi,esi
mov edx,edi
cld
mov ecx,0x80
mov ebx,0x41
xor eax,eax
push eax
lodsb
xor eax,ebx
stosb
loop 0xb7
push esp
pop esi
int3
db 0x0a
要使用 gcc 构建,您要定义 _start
而不是 main
,因此您需要使用 -nostdlib
。喜欢gcc -m32 -nostdlib -static -o key shellcode.o
。这将使 gcc 以您手动执行的方式调用 ld
。
loop
仅适用于 rel8 位移,因此它无法从 ld
将其放置在代码段中的更高地址到达绝对地址 0xb7
。
如果你真的想这样做(但你几乎肯定不想),你可以使用dec ecx / jnz 0xb7
,它将使用 jcc rel32
编码,因此可以通过 EIP + rel32
到达任何绝对地址。或者使用 linker 脚本在非常低的虚拟地址 link TEXT 段,以便 loop rel8
可以到达。
(但无论哪种方式都不是 position-independent。通常 shellcode 应该在被注入到未知地址后工作。如果你真的想跳转到 position-independent shellcode 中的绝对地址,比如要触发特定的页面错误(?),您需要寄存器中的地址并使用 jmp eax
)
但您更有可能想跳转到代码中的其他地方,而不是某些低绝对地址。 在您的分支目标上放置一个标签并使用 dec ecx / jnz label
。 (或者使用 loop
指令,因为您可能正在针对 code-size 进行优化,而不管它是否缓慢。)
如果您从某处借用此代码,可能是在 loop 0xb7
设置 rel8
位移值的汇编器中。或者可能是 NASM 与 org 0x0
和 BITS 32
制作了一个平面二进制文件?但是如果你想分支回到这段代码中的某个地方,使用标签会更有意义。