Sau nhiều thời gian và suy nghĩ, cuối cùng tôi đã giải quyết được vấn đề. Tài nguyên đã giúp tôi giải quyết vấn đề này là Stack smashing code not working on Linux kernel 2.6.38.7... Please help
Thay đổi lớn nhất đã giúp tôi giải quyết vấn đề này là sử dụng disassembly-flavor intel
cho gdb
.
đang
tháo rời (để tham khảo):
0804840c <function>:
804840c: 55 push ebp
804840d: 89 e5 mov ebp,esp
804840f: 83 ec 10 sub esp,0x10
8048412: 8d 45 f7 lea eax,[ebp-0x9]
8048415: 83 c0 14 add eax,0x14
8048418: 89 45 fc mov DWORD PTR [ebp-0x4],eax
804841b: 8b 45 fc mov eax,DWORD PTR [ebp-0x4]
804841e: 8b 00 mov eax,DWORD PTR [eax]
8048420: 8d 50 05 lea edx,[eax+0x5]
8048423: 8b 45 fc mov eax,DWORD PTR [ebp-0x4]
8048426: 89 10 mov DWORD PTR [eax],edx
8048428: c9 leave
8048429: c3 ret
0804842a <main>:
804842a: 55 push ebp
804842b: 89 e5 mov ebp,esp
804842d: 83 e4 f0 and esp,0xfffffff0
8048430: 83 ec 20 sub esp,0x20
8048433: c7 44 24 1c 00 00 00 mov DWORD PTR [esp+0x1c],0x0
804843a: 00
804843b: c7 44 24 08 03 00 00 mov DWORD PTR [esp+0x8],0x3
8048442: 00
8048443: c7 44 24 04 02 00 00 mov DWORD PTR [esp+0x4],0x2
804844a: 00
804844b: c7 04 24 01 00 00 00 mov DWORD PTR [esp],0x1
8048452: e8 b5 ff ff ff call 804840c <function>
8048457: c7 44 24 1c 01 00 00 mov DWORD PTR [esp+0x1c],0x1
804845e: 00
804845f: 8b 44 24 1c mov eax,DWORD PTR [esp+0x1c]
8048463: 89 44 24 04 mov DWORD PTR [esp+0x4],eax
8048467: c7 04 24 18 85 04 08 mov DWORD PTR [esp],0x8048518
804846e: e8 7d fe ff ff call 80482f0 <[email protected]>
8048473: c9 leave
8048474: c3 ret
8048475: 66 90 xchg ax,ax
8048477: 66 90 xchg ax,ax
8048479: 66 90 xchg ax,ax
804847b: 66 90 xchg ax,ax
804847d: 66 90 xchg ax,ax
804847f: 90 nop
Có hai vấn đề với sự hiểu biết của tôi về vấn đề này:
A) vấn đề đầu tiên của tôi đã tìm ra số lượng byte để tràn ret
bên function
. Lần nữa; Tôi đã làm điều này bằng cách sử dụng cú pháp intel để tháo và thấy rằng:
Để đặt ret
ở đúng không gian trong bộ nhớ ret
cần phải được đặt thành EIP
khi hàm được gọi. Không gian địa chỉ tại số 8048412
di chuyển xuống ngăn xếp 0x9
. Bởi vì đây là mã 32 bit; để truy cập vào ret
, sau đó chúng tôi thêm thêm 0x4
byte cho kích thước từ. Để truy cập vào ret
điều đó có nghĩa là ret
được đặt thành 0x9 + 0x4
có 13 chữ số thập phân.
Điều này giải quyết vấn đề đầu tiên khi truy cập vào ret
.
B) Vấn đề thứ hai đang bỏ qua vị trí bộ nhớ 0x8048457
. Điều này được thực hiện bằng cách thêm 7 byte vào (*ret)
làm cho chương trình bỏ qua và thực thi tại 0x804845e
là 00
(NUL
). Điều này chỉ là không hiệu quả; vì vậy tôi đã thêm byte bổ sung và thực thi 8 byte xuống ngăn xếp; do đó dẫn đến x = 0
;
Tôi nhận thấy số byte chính xác là 8 (c7 44 24 1c 01 00 00
là 7 byte) và 00
là một byte. Điều này giải quyết vấn đề cuối cùng của tôi.
mã C sửa đổi của tôi:
void function(int a, int b, int c) {
char buffer1[5];
int *ret;
ret = buffer1 + 13; //tried 11, 14, 20, 40, 38, 43
(*ret) += 8; // tried 5, 8, 12; 8 is correct value!
}
void main() {
int x;
x = 0;
function(1,2,3);
x = 1;
printf("%d\n", x);
}
Moving StackOverflow theo yêu cầu người dùng. (+1, câu hỏi hay.) –
Nếu bạn trừ các địa chỉ giống như trong bài viết đó, bạn nhận được 10 byte :) kiểm tra các liên kết ở phần cuối của câu trả lời của tôi, bù đắp là sai. – iabdalkader
Có một câu trả lời cho biết rằng nó đã được sửa đổi. Đây là [sửa đổi] mới nhất (https://avicoder.me/2016/02/01/smashsatck-revived/) – NathanOliver