|
Message-ID: <alpine.LRH.2.02.1303160056390.13996@argo.troja.mff.cuni.cz>
Date: Sat, 16 Mar 2013 01:25:04 +0100 (CET)
From: Pavel Kankovsky <peak@...o.troja.mff.cuni.cz>
To: owl-dev@...ts.openwall.com
Subject: Re: strace
On Fri, 15 Mar 2013, Pavel Kankovsky wrote:
> On Fri, 15 Mar 2013, Dmitry V. Levin wrote:
>
>> The change of orig_eax offset means that there was a change in the ptrace
>> ABI between 2.6.18 and 2.6.32, and all its users (e.g. strace and gdb)
>> should be rebuilt.
>
> Things appear to be a little more complicated.
>
> As far as I can tell, PTRACE_GETREGS returns data in struct pt_regs
> layout on 2.6.18 and in struct user_regs_struct layout on 2.6.32. Those
> two structs are compatible on 2.6.32 but they are different on 2.6.18
> (i386 arch; x86-64 is probably unaffected).
Uhh... I am sorry. Let me retract this statement, please. I was not
thinking clearly (note to myself: do not write & send any important emails
after 2am) and I misinterpreted the code in 2.6.18 (I quote vanilla
here, RH added some irrelevant stuff):
static unsigned long getreg(struct task_struct *child,
unsigned long regno)
{
unsigned long retval = ~0UL;
switch (regno >> 2) {
case FS:
retval = child->thread.fs;
break;
case GS:
retval = child->thread.gs;
break;
case DS:
case ES:
case SS:
case CS:
retval = 0xffff;
/* fall through */
default:
if (regno > GS*4)
regno -= 2*4;
regno = regno - sizeof(struct pt_regs);
retval &= get_stack_long(child, regno);
}
return retval;
}
I did not pay enough attention to "if (regno > GS*4) regno -= 2*4".
That command skips two elements that are present in user_regs_struct
but are missing in pt_regs:
pt_regs (2.6.18): user_regs_struct (2.6.32):
long ebx; unsigned long bx;
long ecx; unsigned long cx;
long edx; unsigned long dx;
long esi; unsigned long si;
long edi; unsigned long di;
long ebp; unsigned long bp;
long eax; unsigned long ax;
int xds; unsigned long ds;
int xes; unsigned long es;
unsigned long fs;
unsigned long gs;
long orig_eax; unsigned long orig_ax;
long eip; unsigned long ip;
int xcs; unsigned long cs;
long eflags; unsigned long flags;
long esp; unsigned long sp;
int xss; unsigned long ss;
(For some unfathomable reasons, register names in user_regs_struct differ
between kernel headers and Glibc but the layout stays the same.)
There were some changes: GS was migrated to struct pt_regs in 2.6.20
and the code was reengineered completely in 2.6.25. But it appears to me
(now) that its interface has been stable.
I made a small test program PTRACE_GETREGS and I get the expected results
(namely orig_eax == 0x25 == SYS_kill) on RHEL 2.6.18 and on 2.6.32.
0: ebx 0x0000372a
1: ecx 0x00000002
2: edx 0x009c4ff4
3: esi 0x00867ca0
4: edi 0x00000000
5: ebp 0xbffa1b08
6: eax 0x00000000
7: ds 0x0000007b
8: es 0x0000007b
9: fs 0x00000000
10: gs 0x00000033
11: orig_eax 0x00000025 <---- SYS_kill
12: eip 0x006bb402
13: cs 0x00000073
14: eflags 0x00000246
15: esp 0xbffa1a88
16: ss 0x0000007b
17: xxx 0xdeafbeef
--
Pavel Kankovsky aka Peak / Jeremiah 9:21 \
"For death is come up into our MS Windows(tm)..." \ 21st century edition /
View attachment "ptrace_getregs.c" of type "TEXT/PLAIN" (1184 bytes)
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.