我目前正在跟随丹尼斯·安德里斯( Dennis )写的一本关于二进制拆卸和仪器仪表的书。
在后面的一章中,我们已经为ELF类型文件编写了一个注入器。注入器将代码部分放置在0x80000 +偏移量%16处,覆盖. code . at tag部分(只包含与执行无关的信息,因此覆盖它是安全的)。
我正在修改的程序是一个简单的hello_username程序,如下所示:
#include <iostream>
using namespace std;
main()
{
cout << "hello Lucky" << endl;
return 0;
}我放置的代码如下所示:
BITS 64
section .text
global main
main:
push rax
push rcx
push rdx
push rsi
push rdi
push r11
mov rax, 0x1 ;syscall to print (sys_write)
mov rdi, 0x1 ;stdout
lea rsi, [rel $+rankle-$] ;offset to prank
mov rdx, [rel $+size-$] ;length of prank
syscall
pop r11
pop rdi
pop rsi
pop rdx
pop rcx
pop rax
push 0x1080 ;find "entry_point" using readelf program
ret
rankle : db "Yikes! U got pranked!", 0
size : dd 22虽然我认为我们不需要推动rcx和r11,但代码简单明了,我用
nasm -f bin -o pranked.bin hi_there.asm在此之后,我将它与我们编写的程序一起注入,除了注入部分之外,我还覆盖了入口点。以下是操作之前的readelf输出:
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x1080
Start of program headers: 64 (bytes into file)
Start of section headers: 15344 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 11
Size of section headers: 64 (bytes)
Number of section headers: 30
Section header string table index: 29
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 00000000000002a8 000002a8
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.gnu.build-i NOTE 00000000000002c4 000002c4
0000000000000024 0000000000000000 A 0 0 4
[ 3] .note.ABI-tag NOTE 00000000000002e8 000002e8
0000000000000020 0000000000000000 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0000000000000308 00000308
0000000000000028 0000000000000000 A 5 0 8
[ 5] .dynsym DYNSYM 0000000000000330 00000330
0000000000000138 0000000000000018 A 6 1 8
[ 6] .dynstr STRTAB 0000000000000468 00000468
0000000000000163 0000000000000000 A 0 0 1
[ 7] .gnu.version VERSYM 00000000000005cc 000005cc
000000000000001a 0000000000000002 A 5 0 2
[ 8] .gnu.version_r VERNEED 00000000000005e8 000005e8
0000000000000040 0000000000000000 A 6 2 8
[ 9] .rela.dyn RELA 0000000000000628 00000628
0000000000000120 0000000000000018 A 5 0 8
[10] .rela.plt RELA 0000000000000748 00000748
0000000000000060 0000000000000018 AI 5 23 8
[11] .init PROGBITS 0000000000001000 00001000
0000000000000017 0000000000000000 AX 0 0 4
[12] .plt PROGBITS 0000000000001020 00001020
0000000000000050 0000000000000010 AX 0 0 16
[13] .plt.got PROGBITS 0000000000001070 00001070
0000000000000008 0000000000000008 AX 0 0 8
[14] .text PROGBITS 0000000000001080 00001080
00000000000001e1 0000000000000000 AX 0 0 16
[ .... ]您可以看到入口点为0x1080,这是.text部分开始的地方。( _start函数就在这里,用objdump签出)
现在,在注入之后,相同的输出:
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x80370
Start of program headers: 64 (bytes into file)
Start of section headers: 15344 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 11
Size of section headers: 64 (bytes)
Number of section headers: 30
Section header string table index: 29
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 00000000000002a8 000002a8
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.gnu.build-i NOTE 00000000000002c4 000002c4
0000000000000024 0000000000000000 A 0 0 4
[ 3] .init PROGBITS 0000000000001000 00001000
0000000000000017 0000000000000000 AX 0 0 4
[ 4] .gnu.hash GNU_HASH 0000000000000308 00000308
0000000000000028 0000000000000000 A 5 0 8
[ 5] .dynsym DYNSYM 0000000000000330 00000330
0000000000000138 0000000000000018 A 6 1 8
[ 6] .dynstr STRTAB 0000000000000468 00000468
0000000000000163 0000000000000000 A 0 0 1
[ 7] .gnu.version VERSYM 00000000000005cc 000005cc
000000000000001a 0000000000000002 A 5 0 2
[ 8] .gnu.version_r VERNEED 00000000000005e8 000005e8
0000000000000040 0000000000000000 A 6 2 8
[ 9] .rela.dyn RELA 0000000000000628 00000628
0000000000000120 0000000000000018 A 5 0 8
[10] .rela.plt RELA 0000000000000748 00000748
0000000000000060 0000000000000018 AI 5 23 8
[11] .plt PROGBITS 0000000000001020 00001020
0000000000000050 0000000000000010 AX 0 0 16
[12] .plt.got PROGBITS 0000000000001070 00001070
0000000000000008 0000000000000008 AX 0 0 8
[13] .text PROGBITS 0000000000001080 00001080
00000000000001e1 0000000000000000 AX 0 0 16
[...]
[25] .bss NOBITS 0000000000004060 00003048
0000000000000118 0000000000000000 WA 0 0 32
[26] .pranked PROGBITS 0000000000080370 00004370
000000000000004a 0000000000000000 AX 0 0 16
[27] .symtab SYMTAB 0000000000000000 00003070
00000000000006f0 0000000000000018 28 49 8
[28] .strtab STRTAB 0000000000000000 00003760
0000000000000382 0000000000000000 0 0 1
[29] .shstrtab STRTAB 0000000000000000 00003ae2
0000000000000107 0000000000000000 0 0 1您可以看到新的部分在那里,从0x80370开始,ELF头中的新入口点指向它(用十六进制编辑器对其进行了双重检查)。
所以,现在问题开始了:
如果我试图执行这个程序,它会正确地打印出“Yikes!您被恶作剧了!\”,紧接着是分段错误。
这让我发疯了,因为我已经烦躁了一个多星期了!不幸的是,gdb在这里没有多大帮助,但至少我可以在SIGSEV之前获取堆栈框架:
#0 0x0000000000001080 in ?? ()
(gdb) info f
Stack level 0, frame at 0x7fffb20db438:
rip = 0x1080; saved rip = 0x1
called by frame at 0x7fffb20db440
Arglist at 0x7fffb20db428, args:
Locals at 0x7fffb20db428, Previous frame's sp is 0x7fffb20db438
Saved registers:
rip at 0x7fffb20db430这就是我被困的地方。为什么说是1080英寸?()我想,我对入境点的计算也应该是正确的。这个裂口也指向_start函数..。
我怎样才能让它再次跳到正确的入口点呢?我只想为一个你好世界程序写一个国防部,这不应该是太多的黑魔法.
发布于 2019-10-03 00:55:40
我对入口点的计算也应该是正确的,我想。裂口指向_start函数,
_start不可能位于0x1080 (至少不在0x1080上)。
如果readelf告诉您这是_start的地址,那么您有一个与位置无关的可执行文件。
饼可执行文件直到几年前才存在,因此这本书可能没有提到您需要一个非饼类的二进制文件(因为在编写非饼类二进制文件时,您只能构建/运行非饼类二进制文件)。
若要构建非饼式二进制文件,请使用g++ -fno-pie -no-pie hello.cc。在这样做之后,代码注入的其余部分应该像在书中那样工作。
https://stackoverflow.com/questions/58201225
复制相似问题